Skip to content

Commit d8c56a0

Browse files
committed
patch 8.1.0854: xxd does not work with more than 32 bit addresses
Problem: xxd does not work with more than 32 bit addresses. Solution: Add support for 64 bit addresses. (Christer Jensen, closes #3791)
1 parent cbbd0f6 commit d8c56a0

2 files changed

Lines changed: 31 additions & 13 deletions

File tree

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,8 @@ static char *(features[]) =
783783

784784
static int included_patches[] =
785785
{ /* Add new patch number below this line */
786+
/**/
787+
854,
786788
/**/
787789
853,
788790
/**/

src/xxd/xxd.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
* 2011 March Better error handling by Florian Zumbiehl.
5353
* 2011 April Formatting by Bram Moolenaar
5454
* 08.06.2013 Little-endian hexdump (-e) and offset (-o) by Vadim Vygonets.
55+
* 11.01.2019 Add full 64/32 bit range to -o and output by Christer Jensen.
5556
*
5657
* (c) 1990-1998 by Juergen Weigert ([email protected])
5758
*
@@ -90,6 +91,7 @@
9091
#include <stdlib.h>
9192
#include <string.h> /* for strncmp() */
9293
#include <ctype.h> /* for isalnum() */
94+
#include <limits.h>
9395
#if __MWERKS__ && !defined(BEBOX)
9496
# include <unix.h> /* for fdopen() on MAC */
9597
#endif
@@ -204,7 +206,7 @@ static void xxdline __P((FILE *, char *, int));
204206

205207
#define TRY_SEEK /* attempt to use lseek, or skip forward by reading */
206208
#define COLS 256 /* change here, if you ever need more columns */
207-
#define LLEN (12 + (9*COLS-1) + COLS + 2)
209+
#define LLEN ((2*(int)sizeof(unsigned long)) + 4 + (9*COLS-1) + COLS + 2)
208210

209211
char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
210212

@@ -466,7 +468,8 @@ main(int argc, char *argv[])
466468
int ebcdic = 0;
467469
int octspergrp = -1; /* number of octets grouped in output */
468470
int grplen; /* total chars per octet group */
469-
long length = -1, n = 0, seekoff = 0, displayoff = 0;
471+
long length = -1, n = 0, seekoff = 0;
472+
unsigned long displayoff = 0;
470473
static char l[LLEN+1]; /* static because it may be too big for stack */
471474
char *pp;
472475

@@ -536,13 +539,25 @@ main(int argc, char *argv[])
536539
}
537540
else if (!STRNCMP(pp, "-o", 2))
538541
{
542+
int reloffset = 0;
543+
int negoffset = 0;
539544
if (pp[2] && STRNCMP("ffset", pp + 2, 5))
540-
displayoff = (int)strtol(pp + 2, NULL, 0);
545+
displayoff = strtoul(pp + 2, NULL, 0);
541546
else
542547
{
543548
if (!argv[2])
544549
exit_with_usage();
545-
displayoff = (int)strtol(argv[2], NULL, 0);
550+
551+
if (argv[2][0] == '+')
552+
reloffset++;
553+
if (argv[2][reloffset] == '-')
554+
negoffset++;
555+
556+
if (negoffset)
557+
displayoff = ULONG_MAX - strtoul(argv[2] + reloffset+negoffset, NULL, 0) + 1;
558+
else
559+
displayoff = strtoul(argv[2] + reloffset+negoffset, NULL, 0);
560+
546561
argv++;
547562
argc--;
548563
}
@@ -805,31 +820,32 @@ main(int argc, char *argv[])
805820
else /* hextype == HEX_BITS */
806821
grplen = 8 * octspergrp + 1;
807822

823+
int addrlen = 9;
808824
e = 0;
809825
while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
810826
{
811827
if (p == 0)
812828
{
813-
sprintf(l, "%08lx:",
814-
((unsigned long)(n + seekoff + displayoff)) & 0xffffffff);
815-
for (c = 9; c < LLEN; l[c++] = ' ');
829+
addrlen = sprintf(l, "%08lx:",
830+
((unsigned long)(n + seekoff + displayoff)));
831+
for (c = addrlen; c < LLEN; l[c++] = ' ');
816832
}
817833
if (hextype == HEX_NORMAL)
818834
{
819-
l[c = (10 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
835+
l[c = (addrlen + 1 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
820836
l[++c] = hexx[ e & 0xf];
821837
}
822838
else if (hextype == HEX_LITTLEENDIAN)
823839
{
824840
int x = p ^ (octspergrp-1);
825-
l[c = (10 + (grplen * x) / octspergrp)] = hexx[(e >> 4) & 0xf];
841+
l[c = (addrlen + 1 + (grplen * x) / octspergrp)] = hexx[(e >> 4) & 0xf];
826842
l[++c] = hexx[ e & 0xf];
827843
}
828844
else /* hextype == HEX_BITS */
829845
{
830846
int i;
831847

832-
c = (10 + (grplen * p) / octspergrp) - 1;
848+
c = (addrlen + 1 + (grplen * p) / octspergrp) - 1;
833849
for (i = 7; i >= 0; i--)
834850
l[++c] = (e & (1 << i)) ? '1' : '0';
835851
}
@@ -838,7 +854,7 @@ main(int argc, char *argv[])
838854
if (ebcdic)
839855
e = (e < 64) ? '.' : etoa64[e-64];
840856
/* When changing this update definition of LLEN above. */
841-
l[12 + (grplen * cols - 1)/octspergrp + p] =
857+
l[addrlen + 3 + (grplen * cols - 1)/octspergrp + p] =
842858
#ifdef __MVS__
843859
(e >= 64)
844860
#else
@@ -848,7 +864,7 @@ main(int argc, char *argv[])
848864
n++;
849865
if (++p == cols)
850866
{
851-
l[c = (12 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
867+
l[c = (addrlen + 3 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
852868
xxdline(fpo, l, autoskip ? nonzero : 1);
853869
nonzero = 0;
854870
p = 0;
@@ -858,7 +874,7 @@ main(int argc, char *argv[])
858874
die(2);
859875
if (p)
860876
{
861-
l[c = (12 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
877+
l[c = (addrlen + 3 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
862878
xxdline(fpo, l, 1);
863879
}
864880
else if (autoskip)

0 commit comments

Comments
 (0)