Skip to content

Commit 88da86b

Browse files
authored
od: incorrect file offsets after first 16 bytes (#434)
* I observed the file offsets incorrectly jumped from 0 to 17, instead of 0 to 16 * When debugging this I discovered the formatting routines were modifying the value of $data by appending pad bytes * Fix offsets issue by not modifying the value of $data * Using global $len in the format routines is also not correct since the input loop was previously changed and $len will always be 1 * Remove global variable $upformat and provide the unpack format directly to unpack() * Remove unsupported -a flag from the SYNOPSIS
1 parent ca9a191 commit 88da86b

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

bin/od

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use vars qw/ $opt_A $opt_b $opt_c $opt_d $opt_f $opt_i $opt_j $opt_l $opt_N
2626
$opt_o $opt_v $opt_x /;
2727

2828
my ($offset1, $radix, $data, @arr, $len, $fh, $lim);
29-
my ($lastline, $upformat, $pffmt, $strfmt, $ml);
29+
my ($lastline, $pffmt, $strfmt, $ml);
3030

3131
my %charescs = (
3232
0 => ' \0',
@@ -168,19 +168,17 @@ close $fh;
168168
exit EX_SUCCESS;
169169

170170
sub octal1 {
171-
$upformat = 'C*'; # for -b
172171
$pffmt = '%.3o ';
173-
@arr = unpack($upformat,$data);
172+
@arr = unpack 'C*', $data;
174173
$strfmt = $pffmt x (scalar @arr);
175174
}
176175

177176
sub char1 {
178-
$upformat = 'C*'; # for -c
179177
$pffmt = '%s';
180178
$strfmt = $pffmt;
181179

182180
@arr = ();
183-
my @arr1 = unpack($upformat,$data);
181+
my @arr1 = unpack 'C*', $data;
184182
for my $val (@arr1) {
185183
if (exists $charescs{$val}) {
186184
$arr[0] .= $charescs{$val} . " ";
@@ -195,52 +193,72 @@ sub char1 {
195193
}
196194

197195
sub udecimal {
198-
$upformat = 'S*'; # for -d
199-
$data .= "\0" if ($len & 1); # zero-fill 16 bit input
196+
if (length($data) & 1) { # pad to 16 bit
197+
@arr = unpack 'S*', $data . "\0";
198+
}
199+
else {
200+
@arr = unpack 'S*', $data;
201+
}
200202
$pffmt = '%5u ';
201-
@arr = unpack($upformat,$data);
202203
$strfmt = $pffmt x (scalar @arr);
203204
}
204205

205206
sub float {
206-
$upformat = 'f*'; # for -f
207-
my $remain = $len % 4;
208-
$data .= "\0" x $remain if ($remain); # zero-fill 32 bit input
207+
my $remain = length($data) % 4;
208+
if ($remain) { # pad to 32 bit
209+
my $pad = "\0" x $remain;
210+
@arr = unpack 'f*', $data . $pad;
211+
}
212+
else {
213+
@arr = unpack 'f*', $data;
214+
}
209215
$pffmt = '%6.6e ';
210-
@arr = unpack($upformat,$data);
211216
$strfmt = $pffmt x (scalar @arr);
212217
}
213218

214219
sub decimal {
215-
$upformat = 's*'; # for -i
216-
$data .= "\0" if ($len & 1); # zero-fill 16 bit input
220+
if (length($data) & 1) { # pad to 16 bit
221+
@arr = unpack 's*', $data . "\0";
222+
}
223+
else {
224+
@arr = unpack 's*', $data;
225+
}
217226
$pffmt = '%5d ';
218-
@arr = unpack($upformat,$data);
219227
$strfmt = $pffmt x (scalar @arr);
220228
}
221229

222230
sub long {
223-
$upformat = 'L*'; # for -l
224-
my $remain = $len % 4;
225-
$data .= "\0" x $remain if ($remain); # zero-fill 32 bit input
231+
my $remain = length($data) % 4;
232+
if ($remain) { # pad to 32 bit
233+
my $pad = "\0" x $remain;
234+
@arr = unpack 'L*', $data . $pad;
235+
}
236+
else {
237+
@arr = unpack 'L*', $data;
238+
}
226239
$pffmt = '%10ld ';
227-
@arr = unpack($upformat,$data);
228240
$strfmt = $pffmt x (scalar @arr);
229241
}
230242

231243
sub octal2 {
232-
$upformat = 'S*'; # for -o
233-
$data .= "\0" if ($len & 1); # zero-fill 16 bit input
244+
if (length($data) & 1) { # pad to 16 bit
245+
@arr = unpack 'S*', $data . "\0";
246+
}
247+
else {
248+
@arr = unpack 'S*', $data;
249+
}
234250
$pffmt = '%.6o ';
235-
@arr = unpack($upformat,$data);
236251
$strfmt = $pffmt x (scalar @arr);
237252
}
238253

239254
sub hex {
240-
$upformat = 'S*'; # for -x
241-
$data .= "\0" if ($len & 1); # zero-fill 16 bit input
255+
if (length($data) & 1) { # pad to 16 bit
256+
@arr = unpack 'S*', $data . "\0";
257+
}
258+
else {
259+
@arr = unpack 'S*', $data;
260+
}
242261
$pffmt = '%.4x ';
243-
@arr = unpack($upformat,$data);
244262
$strfmt = $pffmt x (scalar @arr);
245263
}
246264

@@ -261,7 +279,7 @@ od - dump files in octal and other formats
261279
262280
=head1 SYNOPSIS
263281
264-
B<od> [ I<-abcdfiloxv> ] [I<-j skip_n_bytes>] [I<-N read_n_bytes>] [ I<-A radix> ] F<filename>
282+
B<od> [ I<-bcdfiloxv> ] [I<-j skip_n_bytes>] [I<-N read_n_bytes>] [ I<-A radix> ] F<filename>
265283
266284
=head1 DESCRIPTION
267285

0 commit comments

Comments
 (0)