aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-16 07:22:14 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-16 07:22:14 +0000
commitbd9874db7485e827a2b9af6d7066c02692cef46d (patch)
treefef8728a85fef7666676a3e94b165f0d9c476ced /libbb
parent018bee6afb0a7b9e09616a52f2f24f65fcf07322 (diff)
downloadbusybox-w32-bd9874db7485e827a2b9af6d7066c02692cef46d.tar.gz
busybox-w32-bd9874db7485e827a2b9af6d7066c02692cef46d.tar.bz2
busybox-w32-bd9874db7485e827a2b9af6d7066c02692cef46d.zip
od,hexdump: fix bug where xrealloc may move pointer,
leaving other pointers dangling (bug 4104). + many style fixes in libbb/dump.c.
Diffstat (limited to 'libbb')
-rw-r--r--libbb/dump.c130
1 files changed, 68 insertions, 62 deletions
diff --git a/libbb/dump.c b/libbb/dump.c
index 8a90aac5a..29c2c85ee 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -14,17 +14,18 @@
14#include "libbb.h" 14#include "libbb.h"
15#include "dump.h" 15#include "dump.h"
16 16
17enum _vflag bb_dump_vflag = FIRST; 17FS *bb_dump_fshead; /* head of format strings */
18FS *bb_dump_fshead; /* head of format strings */ 18off_t bb_dump_skip; /* bytes to skip */
19int bb_dump_blocksize; /* data block size */
20int bb_dump_length = -1; /* max bytes to read */
21smallint /*enum _vflag*/ bb_dump_vflag = FIRST;
22
19static FU *endfu; 23static FU *endfu;
20static char **_argv; 24static char **_argv;
21static off_t savaddress; /* saved address/offset in stream */ 25static off_t savaddress; /* saved address/offset in stream */
22static off_t eaddress; /* end address */ 26static off_t eaddress; /* end address */
23static off_t address; /* address/offset in stream */ 27static off_t address; /* address/offset in stream */
24off_t bb_dump_skip; /* bytes to skip */ 28static int exitval; /* final exit value */
25static int exitval; /* final exit value */
26int bb_dump_blocksize; /* data block size */
27int bb_dump_length = -1; /* max bytes to read */
28 29
29static const char index_str[] ALIGN1 = ".#-+ 0123456789"; 30static const char index_str[] ALIGN1 = ".#-+ 0123456789";
30 31
@@ -78,7 +79,7 @@ int FAST_FUNC bb_dump_size(FS *fs)
78 return cur_size; 79 return cur_size;
79} 80}
80 81
81static void rewrite(FS * fs) 82static void rewrite(FS *fs)
82{ 83{
83 enum { NOTOKAY, USEBCNT, USEPREC } sokay; 84 enum { NOTOKAY, USEBCNT, USEPREC } sokay;
84 PR *pr, **nextpr = NULL; 85 PR *pr, **nextpr = NULL;
@@ -104,7 +105,8 @@ static void rewrite(FS * fs)
104 */ 105 */
105 106
106 /* bb_dump_skip preceding text and up to the next % sign */ 107 /* bb_dump_skip preceding text and up to the next % sign */
107 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1); 108 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1)
109 continue;
108 110
109 /* only text in the string */ 111 /* only text in the string */
110 if (!*p1) { 112 if (!*p1) {
@@ -120,14 +122,17 @@ static void rewrite(FS * fs)
120 if (fu->bcnt) { 122 if (fu->bcnt) {
121 sokay = USEBCNT; 123 sokay = USEBCNT;
122 /* bb_dump_skip to conversion character */ 124 /* bb_dump_skip to conversion character */
123 for (++p1; strchr(index_str, *p1); ++p1); 125 for (++p1; strchr(index_str, *p1); ++p1)
126 continue;
124 } else { 127 } else {
125 /* bb_dump_skip any special chars, field width */ 128 /* bb_dump_skip any special chars, field width */
126 while (strchr(index_str + 1, *++p1)); 129 while (strchr(index_str + 1, *++p1))
130 continue;
127 if (*p1 == '.' && isdigit(*++p1)) { 131 if (*p1 == '.' && isdigit(*++p1)) {
128 sokay = USEPREC; 132 sokay = USEPREC;
129 prec = atoi(p1); 133 prec = atoi(p1);
130 while (isdigit(*++p1)); 134 while (isdigit(*++p1))
135 continue;
131 } else 136 } else
132 sokay = NOTOKAY; 137 sokay = NOTOKAY;
133 } 138 }
@@ -139,12 +144,11 @@ static void rewrite(FS * fs)
139 * rewrite the format as necessary, set up blank- 144 * rewrite the format as necessary, set up blank-
140 * pbb_dump_adding for end of data. 145 * pbb_dump_adding for end of data.
141 */ 146 */
142
143 if (*p1 == 'c') { 147 if (*p1 == 'c') {
144 pr->flags = F_CHAR; 148 pr->flags = F_CHAR;
145 DO_BYTE_COUNT_1: 149 DO_BYTE_COUNT_1:
146 byte_count_str = "\001"; 150 byte_count_str = "\001";
147 DO_BYTE_COUNT: 151 DO_BYTE_COUNT:
148 if (fu->bcnt) { 152 if (fu->bcnt) {
149 do { 153 do {
150 if (fu->bcnt == *byte_count_str) { 154 if (fu->bcnt == *byte_count_str) {
@@ -160,7 +164,7 @@ static void rewrite(FS * fs)
160 } else if (*p1 == 'l') { 164 } else if (*p1 == 'l') {
161 ++p2; 165 ++p2;
162 ++p1; 166 ++p1;
163 DO_INT_CONV: 167 DO_INT_CONV:
164 { 168 {
165 const char *e; 169 const char *e;
166 e = strchr(lcc, *p1); 170 e = strchr(lcc, *p1);
@@ -221,7 +225,7 @@ static void rewrite(FS * fs)
221 goto DO_BAD_CONV_CHAR; 225 goto DO_BAD_CONV_CHAR;
222 } 226 }
223 } else { 227 } else {
224 DO_BAD_CONV_CHAR: 228 DO_BAD_CONV_CHAR:
225 bb_error_msg_and_die("bad conversion character %%%s", p1); 229 bb_error_msg_and_die("bad conversion character %%%s", p1);
226 } 230 }
227 231
@@ -233,16 +237,17 @@ static void rewrite(FS * fs)
233 p1[1] = '\0'; 237 p1[1] = '\0';
234 pr->fmt = xstrdup(fmtp); 238 pr->fmt = xstrdup(fmtp);
235 *p2 = savech; 239 *p2 = savech;
236 pr->cchar = pr->fmt + (p1 - fmtp); 240 //Too early! xrealloc can move pr->fmt!
241 //pr->cchar = pr->fmt + (p1 - fmtp);
237 242
238 /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost. 243 /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost.
239 * Skip subsequent text and up to the next % sign and tack the 244 * Skip subsequent text and up to the next % sign and tack the
240 * additional text onto fmt: eg. if fmt is "%x is a HEX number", 245 * additional text onto fmt: eg. if fmt is "%x is a HEX number",
241 * we lose the " is a HEX number" part of fmt. 246 * we lose the " is a HEX number" part of fmt.
242 */ 247 */
243 for (p3 = p2; *p3 && *p3 != '%'; p3++); 248 for (p3 = p2; *p3 && *p3 != '%'; p3++)
244 if (p3 > p2) 249 continue;
245 { 250 if (p3 > p2) {
246 savech = *p3; 251 savech = *p3;
247 *p3 = '\0'; 252 *p3 = '\0';
248 pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt) + (p3-p2) + 1); 253 pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt) + (p3-p2) + 1);
@@ -251,6 +256,7 @@ static void rewrite(FS * fs)
251 p2 = p3; 256 p2 = p3;
252 } 257 }
253 258
259 pr->cchar = pr->fmt + (p1 - fmtp);
254 fmtp = p2; 260 fmtp = p2;
255 261
256 /* only one conversion character if byte count */ 262 /* only one conversion character if byte count */
@@ -276,9 +282,11 @@ static void rewrite(FS * fs)
276 * gets output from the last iteration of the format unit. 282 * gets output from the last iteration of the format unit.
277 */ 283 */
278 for (fu = fs->nextfu;; fu = fu->nextfu) { 284 for (fu = fs->nextfu;; fu = fu->nextfu) {
279 if (!fu->nextfu && fs->bcnt < bb_dump_blocksize && 285 if (!fu->nextfu && fs->bcnt < bb_dump_blocksize
280 !(fu->flags & F_SETREP) && fu->bcnt) 286 && !(fu->flags & F_SETREP) && fu->bcnt
287 ) {
281 fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt; 288 fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt;
289 }
282 if (fu->reps > 1) { 290 if (fu->reps > 1) {
283 for (pr = fu->nextpr;; pr = pr->nextpr) 291 for (pr = fu->nextpr;; pr = pr->nextpr)
284 if (!pr->nextpr) 292 if (!pr->nextpr)
@@ -377,7 +385,7 @@ static unsigned char *get(void)
377 * and no other files are available, zero-pad the rest of the 385 * and no other files are available, zero-pad the rest of the
378 * block and set the end flag. 386 * block and set the end flag.
379 */ 387 */
380 if (!bb_dump_length || (ateof && !next((char **) NULL))) { 388 if (!bb_dump_length || (ateof && !next(NULL))) {
381 if (need == bb_dump_blocksize) { 389 if (need == bb_dump_blocksize) {
382 return NULL; 390 return NULL;
383 } 391 }
@@ -387,12 +395,12 @@ static unsigned char *get(void)
387 } 395 }
388 return NULL; 396 return NULL;
389 } 397 }
390 memset((char *) curp + nread, 0, need); 398 memset(curp + nread, 0, need);
391 eaddress = address + nread; 399 eaddress = address + nread;
392 return curp; 400 return curp;
393 } 401 }
394 n = fread((char *) curp + nread, sizeof(unsigned char), 402 n = fread(curp + nread, sizeof(unsigned char),
395 bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin); 403 bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin);
396 if (!n) { 404 if (!n) {
397 if (ferror(stdin)) { 405 if (ferror(stdin)) {
398 bb_simple_perror_msg(_argv[-1]); 406 bb_simple_perror_msg(_argv[-1]);
@@ -407,7 +415,8 @@ static unsigned char *get(void)
407 need -= n; 415 need -= n;
408 if (!need) { 416 if (!need) {
409 if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST 417 if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
410 || memcmp(curp, savp, bb_dump_blocksize)) { 418 || memcmp(curp, savp, bb_dump_blocksize)
419 ) {
411 if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) { 420 if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) {
412 bb_dump_vflag = WAIT; 421 bb_dump_vflag = WAIT;
413 } 422 }
@@ -426,7 +435,7 @@ static unsigned char *get(void)
426 } 435 }
427} 436}
428 437
429static void bpad(PR * pr) 438static void bpad(PR *pr)
430{ 439{
431 char *p1, *p2; 440 char *p1, *p2;
432 441
@@ -436,10 +445,13 @@ static void bpad(PR * pr)
436 */ 445 */
437 pr->flags = F_BPAD; 446 pr->flags = F_BPAD;
438 *pr->cchar = 's'; 447 *pr->cchar = 's';
439 for (p1 = pr->fmt; *p1 != '%'; ++p1); 448 for (p1 = pr->fmt; *p1 != '%'; ++p1)
449 continue;
440 for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1) 450 for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1)
441 if (pr->nospace) pr->nospace--; 451 if (pr->nospace)
442 while ((*p2++ = *p1++) != 0); 452 pr->nospace--;
453 while ((*p2++ = *p1++) != 0)
454 continue;
443} 455}
444 456
445static const char conv_str[] ALIGN1 = 457static const char conv_str[] ALIGN1 =
@@ -454,7 +466,7 @@ static const char conv_str[] ALIGN1 =
454 ; 466 ;
455 467
456 468
457static void conv_c(PR * pr, unsigned char * p) 469static void conv_c(PR *pr, unsigned char *p)
458{ 470{
459 const char *str = conv_str; 471 const char *str = conv_str;
460 char buf[10]; 472 char buf[10];
@@ -469,7 +481,7 @@ static void conv_c(PR * pr, unsigned char * p)
469 481
470 if (isprint(*p)) { 482 if (isprint(*p)) {
471 *pr->cchar = 'c'; 483 *pr->cchar = 'c';
472 (void) printf(pr->fmt, *p); 484 printf(pr->fmt, *p);
473 } else { 485 } else {
474 sprintf(buf, "%03o", (int) *p); 486 sprintf(buf, "%03o", (int) *p);
475 str = buf; 487 str = buf;
@@ -479,7 +491,7 @@ static void conv_c(PR * pr, unsigned char * p)
479 } 491 }
480} 492}
481 493
482static void conv_u(PR * pr, unsigned char * p) 494static void conv_u(PR *pr, unsigned char *p)
483{ 495{
484 static const char list[] ALIGN1 = 496 static const char list[] ALIGN1 =
485 "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0" 497 "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
@@ -511,7 +523,6 @@ static void display(void)
511 PR *pr; 523 PR *pr;
512 int cnt; 524 int cnt;
513 unsigned char *bp; 525 unsigned char *bp;
514
515 off_t saveaddress; 526 off_t saveaddress;
516 unsigned char savech = 0, *savebp; 527 unsigned char savech = 0, *savebp;
517 528
@@ -536,7 +547,7 @@ static void display(void)
536/* PRINT; */ 547/* PRINT; */
537 switch (pr->flags) { 548 switch (pr->flags) {
538 case F_ADDRESS: 549 case F_ADDRESS:
539 printf(pr->fmt, (unsigned int) address); 550 printf(pr->fmt, (unsigned) address);
540 break; 551 break;
541 case F_BPAD: 552 case F_BPAD:
542 printf(pr->fmt, ""); 553 printf(pr->fmt, "");
@@ -553,13 +564,11 @@ static void display(void)
553 564
554 switch (pr->bcnt) { 565 switch (pr->bcnt) {
555 case 4: 566 case 4:
556 memmove((char *) &fval, (char *) bp, 567 memmove(&fval, bp, sizeof(fval));
557 sizeof(fval));
558 printf(pr->fmt, fval); 568 printf(pr->fmt, fval);
559 break; 569 break;
560 case 8: 570 case 8:
561 memmove((char *) &dval, (char *) bp, 571 memmove(&dval, bp, sizeof(dval));
562 sizeof(dval));
563 printf(pr->fmt, dval); 572 printf(pr->fmt, dval);
564 break; 573 break;
565 } 574 }
@@ -574,13 +583,11 @@ static void display(void)
574 printf(pr->fmt, (int) *bp); 583 printf(pr->fmt, (int) *bp);
575 break; 584 break;
576 case 2: 585 case 2:
577 memmove((char *) &sval, (char *) bp, 586 memmove(&sval, bp, sizeof(sval));
578 sizeof(sval));
579 printf(pr->fmt, (int) sval); 587 printf(pr->fmt, (int) sval);
580 break; 588 break;
581 case 4: 589 case 4:
582 memmove((char *) &ival, (char *) bp, 590 memmove(&ival, bp, sizeof(ival));
583 sizeof(ival));
584 printf(pr->fmt, ival); 591 printf(pr->fmt, ival);
585 break; 592 break;
586 } 593 }
@@ -599,21 +606,19 @@ static void display(void)
599 conv_u(pr, bp); 606 conv_u(pr, bp);
600 break; 607 break;
601 case F_UINT:{ 608 case F_UINT:{
602 unsigned int ival; 609 unsigned ival;
603 unsigned short sval; 610 unsigned short sval;
604 611
605 switch (pr->bcnt) { 612 switch (pr->bcnt) {
606 case 1: 613 case 1:
607 printf(pr->fmt, (unsigned int) * bp); 614 printf(pr->fmt, (unsigned) *bp);
608 break; 615 break;
609 case 2: 616 case 2:
610 memmove((char *) &sval, (char *) bp, 617 memmove(&sval, bp, sizeof(sval));
611 sizeof(sval)); 618 printf(pr->fmt, (unsigned) sval);
612 printf(pr->fmt, (unsigned int) sval);
613 break; 619 break;
614 case 4: 620 case 4:
615 memmove((char *) &ival, (char *) bp, 621 memmove(&ival, bp, sizeof(ival));
616 sizeof(ival));
617 printf(pr->fmt, ival); 622 printf(pr->fmt, ival);
618 break; 623 break;
619 } 624 }
@@ -642,10 +647,10 @@ static void display(void)
642 for (pr = endfu->nextpr; pr; pr = pr->nextpr) { 647 for (pr = endfu->nextpr; pr; pr = pr->nextpr) {
643 switch (pr->flags) { 648 switch (pr->flags) {
644 case F_ADDRESS: 649 case F_ADDRESS:
645 (void) printf(pr->fmt, (unsigned int) eaddress); 650 printf(pr->fmt, (unsigned) eaddress);
646 break; 651 break;
647 case F_TEXT: 652 case F_TEXT:
648 (void) printf(pr->fmt); 653 printf(pr->fmt);
649 break; 654 break;
650 } 655 }
651 } 656 }
@@ -676,10 +681,11 @@ int FAST_FUNC bb_dump_dump(char **argv)
676 681
677void FAST_FUNC bb_dump_add(const char *fmt) 682void FAST_FUNC bb_dump_add(const char *fmt)
678{ 683{
684 static FS **nextfs;
685
679 const char *p; 686 const char *p;
680 char *p1; 687 char *p1;
681 char *p2; 688 char *p2;
682 static FS **nextfs;
683 FS *tfs; 689 FS *tfs;
684 FU *tfu, **nextfu; 690 FU *tfu, **nextfu;
685 const char *savep; 691 const char *savep;
@@ -712,7 +718,8 @@ void FAST_FUNC bb_dump_add(const char *fmt)
712 718
713 /* if leading digit, repetition count */ 719 /* if leading digit, repetition count */
714 if (isdigit(*p)) { 720 if (isdigit(*p)) {
715 for (savep = p; isdigit(*p); ++p); 721 for (savep = p; isdigit(*p); ++p)
722 continue;
716 if (!isspace(*p) && *p != '/') { 723 if (!isspace(*p) && *p != '/') {
717 bb_error_msg_and_die("bad format {%s}", fmt); 724 bb_error_msg_and_die("bad format {%s}", fmt);
718 } 725 }
@@ -732,7 +739,8 @@ void FAST_FUNC bb_dump_add(const char *fmt)
732 if (isdigit(*p)) { 739 if (isdigit(*p)) {
733// TODO: use bb_strtou 740// TODO: use bb_strtou
734 savep = p; 741 savep = p;
735 do p++; while (isdigit(*p)); 742 while (isdigit(*++p))
743 continue;
736 if (!isspace(*p)) { 744 if (!isspace(*p)) {
737 bb_error_msg_and_die("bad format {%s}", fmt); 745 bb_error_msg_and_die("bad format {%s}", fmt);
738 } 746 }
@@ -750,9 +758,7 @@ void FAST_FUNC bb_dump_add(const char *fmt)
750 bb_error_msg_and_die("bad format {%s}", fmt); 758 bb_error_msg_and_die("bad format {%s}", fmt);
751 } 759 }
752 } 760 }
753 tfu->fmt = xmalloc(p - savep + 1); 761 tfu->fmt = xstrndup(savep, p - savep);
754 strncpy(tfu->fmt, savep, p - savep);
755 tfu->fmt[p - savep] = '\0';
756/* escape(tfu->fmt); */ 762/* escape(tfu->fmt); */
757 763
758 p1 = tfu->fmt; 764 p1 = tfu->fmt;