Changeset 4117 for zzuf/trunk/src
- Timestamp:
- Dec 12, 2009, 11:20:22 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
zzuf/trunk/src/libzzuf/lib-stream.c
r4114 r4117 214 214 /* 215 215 * fopen, fopen64 etc. 216 */ 217 218 #if defined HAVE_DARWIN_STDIO /* Fuzz fp if we have __srefill() */ 219 # define FOPEN_FUZZ() \ 220 _zz_fuzz(fd, get_stream_ptr(ret), get_stream_cnt(ret)) 221 #else 222 # define FOPEN_FUZZ() 223 #endif 216 * freopen, freopen64 etc. 217 * 218 * Strategy: we call the original function, register the new file descriptor 219 * and immediately fuzz whatever's preloaded in the stream structure. 220 */ 224 221 225 222 #define FOPEN(myfopen) \ … … 236 233 int fd = fileno(ret); \ 237 234 _zz_register(fd); \ 235 _zz_fuzz(fd, get_stream_ptr(ret), get_stream_cnt(ret)); \ 238 236 debug("%s(\"%s\", \"%s\") = [%i]", __func__, path, mode, fd); \ 239 237 debug_stream("new", ret); \ 240 FOPEN_FUZZ(); \241 238 } \ 242 239 } while(0) 243 244 FILE *NEW(fopen)(const char *path, const char *mode)245 {246 FILE *ret; FOPEN(fopen); return ret;247 }248 249 #if defined HAVE_FOPEN64250 FILE *NEW(fopen64)(const char *path, const char *mode)251 {252 FILE *ret; FOPEN(fopen64); return ret;253 }254 #endif255 256 #if defined HAVE___FOPEN64257 FILE *NEW(__fopen64)(const char *path, const char *mode)258 {259 FILE *ret; FOPEN(__fopen64); return ret;260 }261 #endif262 263 /*264 * freopen, freopen64 etc.265 */266 240 267 241 #define FREOPEN(myfreopen) \ … … 282 256 fd1 = fileno(ret); \ 283 257 _zz_register(fd1); \ 258 _zz_fuzz(fd1, get_stream_ptr(ret), get_stream_cnt(ret)); \ 284 259 disp = 1; \ 285 260 } \ … … 289 264 } while(0) 290 265 266 FILE *NEW(fopen)(const char *path, const char *mode) 267 { 268 FILE *ret; FOPEN(fopen); return ret; 269 } 270 271 #if defined HAVE_FOPEN64 272 FILE *NEW(fopen64)(const char *path, const char *mode) 273 { 274 FILE *ret; FOPEN(fopen64); return ret; 275 } 276 #endif 277 278 #if defined HAVE___FOPEN64 279 FILE *NEW(__fopen64)(const char *path, const char *mode) 280 { 281 FILE *ret; FOPEN(__fopen64); return ret; 282 } 283 #endif 284 291 285 FILE *NEW(freopen)(const char *path, const char *mode, FILE *stream) 292 286 { … … 310 304 /* 311 305 * fseek, fseeko etc. 312 */ 313 314 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */ 315 # define FSEEK_FUZZ() 316 #else 317 # define FSEEK_FUZZ() \ 318 if(ret == 0) \ 319 { \ 320 /* FIXME: check what happens when fseek()ing a pipe */ \ 321 switch(whence) \ 322 { \ 323 case SEEK_END: \ 324 offset = MYFTELL(stream); \ 325 /* fall through */ \ 326 case SEEK_SET: \ 327 _zz_setpos(fd, offset); \ 328 break; \ 329 case SEEK_CUR: \ 330 _zz_addpos(fd, offset); \ 331 break; \ 332 } \ 333 } 334 #endif 306 * fsetpos64, __fsetpos64 307 * rewind 308 * 309 * Strategy: we store the previous file position and internal buffer 310 * status, then call the original function. If the new file position 311 * lies outside the previous internal buffer, it means the buffer has 312 * been invalidated, so we fuzz whatever's preloaded in it. 313 */ 335 314 336 315 #define FSEEK(myfseek) \ 337 316 do \ 338 317 { \ 318 int64_t oldpos, newpos; \ 319 int oldoff, oldcnt; \ 339 320 int fd; \ 340 321 LOADSYM(myfseek); \ … … 343 324 return ORIG(myfseek)(stream, offset, whence); \ 344 325 debug_stream("old", stream); \ 326 /* FIXME: ftell() will return -1 on a pipe such as stdin */ \ 327 oldpos = MYFTELL(stream); \ 328 oldoff = get_stream_off(stream); \ 329 oldcnt = get_stream_cnt(stream); \ 345 330 _zz_lock(fd); \ 346 331 ret = ORIG(myfseek)(stream, offset, whence); \ 347 332 _zz_unlock(fd); \ 333 newpos = MYFTELL(stream); \ 334 if (newpos > oldpos + oldcnt || newpos < oldpos - oldoff) \ 335 { \ 336 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 337 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 338 get_stream_cnt(stream) + get_stream_off(stream)); \ 339 } \ 340 _zz_setpos(fd, newpos); \ 348 341 debug("%s([%i], %lli, %i) = %i", __func__, \ 349 342 fd, (long long int)offset, whence, ret); \ 350 FSEEK_FUZZ() \351 343 debug_stream("new", stream); \ 352 344 } while(0) 353 354 int NEW(fseek)(FILE *stream, long offset, int whence)355 {356 int ret; FSEEK(fseek); return ret;357 }358 359 #if defined HAVE_FSEEKO360 int NEW(fseeko)(FILE *stream, off_t offset, int whence)361 {362 int ret; FSEEK(fseeko); return ret;363 }364 #endif365 366 #if defined HAVE_FSEEKO64367 int NEW(fseeko64)(FILE *stream, off64_t offset, int whence)368 {369 int ret; FSEEK(fseeko64); return ret;370 }371 #endif372 373 #if defined HAVE___FSEEKO64374 int NEW(__fseeko64)(FILE *stream, off64_t offset, int whence)375 {376 int ret; FSEEK(__fseeko64); return ret;377 }378 #endif379 380 /*381 * fsetpos64, __fsetpos64382 */383 345 384 346 #define FSETPOS(myfsetpos) \ 385 347 do \ 386 348 { \ 349 int64_t oldpos, newpos; \ 350 int oldoff, oldcnt; \ 387 351 int fd; \ 388 352 LOADSYM(myfsetpos); \ … … 391 355 return ORIG(myfsetpos)(stream, pos); \ 392 356 debug_stream("old", stream); \ 357 /* FIXME: ftell() will return -1 on a pipe such as stdin */ \ 358 oldpos = MYFTELL(stream); \ 359 oldoff = get_stream_off(stream); \ 360 oldcnt = get_stream_cnt(stream); \ 393 361 _zz_lock(fd); \ 394 362 ret = ORIG(myfsetpos)(stream, pos); \ 395 363 _zz_unlock(fd); \ 364 newpos = MYFTELL(stream); \ 365 if (newpos > oldpos + oldcnt || newpos < oldpos - oldoff) \ 366 { \ 367 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 368 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 369 get_stream_cnt(stream) + get_stream_off(stream)); \ 370 } \ 371 _zz_setpos(fd, (int64_t)FPOS_CAST(*pos)); \ 396 372 debug("%s([%i], %lli) = %i", __func__, \ 397 373 fd, (long long int)FPOS_CAST(*pos), ret); \ 398 _zz_setpos(fd, (int64_t)FPOS_CAST(*pos)); \399 374 debug_stream("new", stream); \ 400 375 } \ 401 376 while(0) 402 377 378 #define REWIND(myrewind) \ 379 do \ 380 { \ 381 int64_t oldpos, newpos; \ 382 int oldoff, oldcnt; \ 383 int fd; \ 384 LOADSYM(rewind); \ 385 fd = fileno(stream); \ 386 if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \ 387 return ORIG(rewind)(stream); \ 388 debug_stream("old", stream); \ 389 /* FIXME: ftell() will return -1 on a pipe such as stdin */ \ 390 oldpos = MYFTELL(stream); \ 391 oldoff = get_stream_off(stream); \ 392 oldcnt = get_stream_cnt(stream); \ 393 _zz_lock(fd); \ 394 ORIG(rewind)(stream); \ 395 _zz_unlock(fd); \ 396 newpos = MYFTELL(stream); \ 397 if (newpos > oldpos + oldcnt || newpos < oldpos - oldoff) \ 398 { \ 399 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 400 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 401 get_stream_cnt(stream) + get_stream_off(stream)); \ 402 } \ 403 _zz_setpos(fd, newpos); \ 404 debug("%s([%i])", __func__, fd); \ 405 debug_stream("new", stream); \ 406 } while(0) 407 408 int NEW(fseek)(FILE *stream, long offset, int whence) 409 { 410 int ret; FSEEK(fseek); return ret; 411 } 412 413 #if defined HAVE_FSEEKO 414 int NEW(fseeko)(FILE *stream, off_t offset, int whence) 415 { 416 int ret; FSEEK(fseeko); return ret; 417 } 418 #endif 419 420 #if defined HAVE_FSEEKO64 421 int NEW(fseeko64)(FILE *stream, off64_t offset, int whence) 422 { 423 int ret; FSEEK(fseeko64); return ret; 424 } 425 #endif 426 427 #if defined HAVE___FSEEKO64 428 int NEW(__fseeko64)(FILE *stream, off64_t offset, int whence) 429 { 430 int ret; FSEEK(__fseeko64); return ret; 431 } 432 #endif 433 403 434 #if defined HAVE_FSETPOS64 404 435 int NEW(fsetpos64)(FILE *stream, const fpos64_t *pos) … … 415 446 #endif 416 447 417 /*418 * rewind419 */420 421 448 void NEW(rewind)(FILE *stream) 422 449 { 423 int fd; 424 425 LOADSYM(rewind); 426 fd = fileno(stream); 427 if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) 428 { 429 ORIG(rewind)(stream); 430 return; 431 } 432 433 _zz_lock(fd); 434 ORIG(rewind)(stream); 435 _zz_unlock(fd); 436 debug("%s([%i])", __func__, fd); 437 438 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */ 439 #else 440 /* FIXME: check what happens when rewind()ing a pipe */ 441 _zz_setpos(fd, 0); 442 #endif 450 REWIND(rewind); 443 451 } 444 452 445 453 /* 446 454 * fread, fread_unlocked 447 */ 448 449 /* Compute how many bytes from the stream were already fuzzed by __filbuf, 450 * __srget or __uflow, and store it in already_fuzzed. If these functions 451 * are not available, do nothing. */ 452 #if defined HAVE_BSD_STDIO 453 # define FREAD_PREFUZZ(fd, oldpos) \ 455 * 456 * Strategy: we store the previous file position and internal buffer 457 * status, then call the original function. If the new file position 458 * lies outside the previous internal buffer, it means the buffer has 459 * been invalidated, so we fuzz whatever's preloaded in it. 460 */ 461 462 #define FREAD(myfread) /* NEW */ \ 454 463 do \ 455 464 { \ 456 int64_t tmp = _zz_getpos(fd); \ 457 _zz_setpos(fd, oldpos); \ 458 already_fuzzed = _zz_getfuzzed(fd); \ 459 _zz_setpos(fd, tmp); \ 460 } \ 461 while(0) 462 #else 463 # define FREAD_PREFUZZ(fd, oldpos) do {} while(0) 464 #endif 465 466 /* Fuzz the data returned by fread(). If a __fillbuf mechanism already 467 * fuzzed some of our data, we skip the relevant amount of bytes. If we 468 * have __srefill, we just do nothing because that function is the only 469 * one that actually fuzzes things. */ 470 #if defined HAVE_DARWIN_STDIO 471 # define FREAD_FUZZ(fd, oldpos) \ 472 do \ 473 { \ 474 debug("%s(%p, %li, %li, [%i]) = %li", __func__, ptr, \ 475 (long int)size, (long int)nmemb, fd, (long int)ret); \ 476 } while(0) 477 #else 478 # define FREAD_FUZZ(fd, oldpos) \ 479 do \ 480 { \ 481 int64_t newpos = MYFTELL(stream); \ 482 /* XXX: the number of bytes read is not ret * size, because \ 483 * a partial read may have advanced the stream pointer. However, \ 484 * when reading from a pipe ftell() will return 0, and ret * size \ 485 * is then better than nothing. */ \ 486 if(newpos <= 0) \ 487 { \ 488 oldpos = _zz_getpos(fd); \ 489 newpos = oldpos + ret * size; \ 490 } \ 491 if(newpos != oldpos) \ 492 { \ 493 char *b = ptr; \ 494 /* Skip bytes that were already fuzzed by __filbuf or __srget */ \ 495 if(newpos > oldpos + already_fuzzed) \ 496 { \ 497 _zz_setpos(fd, oldpos + already_fuzzed); \ 498 _zz_fuzz(fd, ptr, newpos - oldpos - already_fuzzed); \ 499 /* FIXME: we need to fuzz the extra bytes that may have been \ 500 * read by the fread call we just made, or subsequent calls \ 501 * to getc_unlocked may miss them. */ \ 502 _zz_setpos(fd, newpos); \ 503 _zz_fuzz(fd, get_stream_ptr(stream), get_stream_cnt(stream)); \ 504 _zz_setfuzzed(fd, get_stream_cnt(stream)); \ 505 /* FIXME: *AND* we need to fuzz the buffer before the current \ 506 * position, in case fseek() causes us to rewind. */ \ 507 } \ 508 _zz_setpos(fd, newpos); \ 509 if(newpos >= oldpos + 4) \ 510 debug("%s(%p, %li, %li, [%i]) = %li \"%c%c%c%c...", __func__, \ 511 ptr, (long int)size, (long int)nmemb, fd, \ 512 (long int)ret, b[0], b[1], b[2], b[3]); \ 513 else \ 514 debug("%s(%p, %li, %li, [%i]) = %li \"%c...", __func__, ptr, \ 515 (long int)size, (long int)nmemb, fd, \ 516 (long int)ret, b[0]); \ 517 } \ 518 else \ 519 debug("%s(%p, %li, %li, [%i]) = %li", __func__, ptr, \ 520 (long int)size, (long int)nmemb, fd, (long int)ret); \ 521 } while(0) 522 #endif 523 524 #define FREAD(myfread) \ 525 do \ 526 { \ 527 int64_t oldpos; \ 528 int fd, already_fuzzed = 0; \ 465 int64_t oldpos, newpos; \ 466 uint8_t *b = ptr;\ 467 int oldoff, oldcnt; \ 468 int fd; \ 529 469 LOADSYM(myfread); \ 530 470 fd = fileno(stream); \ … … 532 472 return ORIG(myfread)(ptr, size, nmemb, stream); \ 533 473 debug_stream("old", stream); \ 474 /* FIXME: ftell() will return -1 on a pipe such as stdin */ \ 534 475 oldpos = MYFTELL(stream); \ 535 _zz_setpos(fd, oldpos); \ 476 oldoff = get_stream_off(stream); \ 477 oldcnt = get_stream_cnt(stream); \ 536 478 _zz_lock(fd); \ 537 479 ret = ORIG(myfread)(ptr, size, nmemb, stream); \ 538 480 _zz_unlock(fd); \ 539 FREAD_PREFUZZ(fd, oldpos); \ 540 FREAD_FUZZ(fd, oldpos); \ 481 newpos = MYFTELL(stream); \ 482 if (newpos > oldpos + oldcnt) \ 483 { \ 484 /* Fuzz returned data that wasn't in the old internal buffer */ \ 485 _zz_setpos(fd, oldpos + oldcnt); \ 486 _zz_fuzz(fd, b + oldcnt, newpos - oldpos - oldcnt); \ 487 /* Fuzz the internal stream buffer */ \ 488 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 489 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 490 get_stream_cnt(stream) + get_stream_off(stream)); \ 491 } \ 492 _zz_setpos(fd, newpos); \ 493 if (newpos > oldpos + 4) \ 494 debug("%s(%p, %li, %li, [%i]) = %li \"%c%c%c%c...", __func__, \ 495 ptr, (long int)size, (long int)nmemb, fd, \ 496 (long int)ret, b[0], b[1], b[2], b[3]); \ 497 else if (newpos > oldpos) \ 498 debug("%s(%p, %li, %li, [%i]) = %li \"%c...", __func__, ptr, \ 499 (long int)size, (long int)nmemb, fd, \ 500 (long int)ret, b[0]); \ 501 else \ 502 debug("%s(%p, %li, %li, [%i]) = %li", __func__, ptr, \ 503 (long int)size, (long int)nmemb, fd, (long int)ret); \ 541 504 debug_stream("new", stream); \ 542 505 } while(0) … … 557 520 /* 558 521 * getc, getchar, fgetc etc. 559 */ 560 561 #if defined HAVE_BSD_STDIO 562 # define FGETC_PREFUZZ already_fuzzed = _zz_getfuzzed(fd); 563 #else 564 # define FGETC_PREFUZZ 565 #endif 566 567 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */ 568 # define FGETC_FUZZ 569 #else 570 # define FGETC_FUZZ \ 571 if(ret != EOF) \ 572 { \ 573 uint8_t ch = ret; \ 574 if(already_fuzzed <= 0) \ 575 _zz_fuzz(fd, &ch, 1); \ 576 _zz_addpos(fd, 1); \ 577 ret = ch; \ 578 } 579 #endif 522 * 523 * Strategy: we store the previous file position and internal buffer 524 * status, then call the original function. If the new file position 525 * lies outside the previous internal buffer, it means the buffer has 526 * been invalidated, so we fuzz whatever's preloaded in it. 527 */ 580 528 581 529 #define FGETC(myfgetc, s, arg) \ 582 530 do { \ 583 int fd, already_fuzzed = 0; \ 531 int64_t oldpos, newpos; \ 532 int oldoff, oldcnt; \ 533 int fd; \ 584 534 LOADSYM(myfgetc); \ 585 535 fd = fileno(s); \ … … 587 537 return ORIG(myfgetc)(arg); \ 588 538 debug_stream("old", s); \ 589 _zz_setpos(fd, MYFTELL(s)); \ 539 oldpos = MYFTELL(s); \ 540 oldoff = get_stream_off(s); \ 541 oldcnt = get_stream_cnt(s); \ 590 542 _zz_lock(fd); \ 591 543 ret = ORIG(myfgetc)(arg); \ 592 544 _zz_unlock(fd); \ 593 FGETC_PREFUZZ \ 594 FGETC_FUZZ \ 545 newpos = MYFTELL(s); \ 546 if (oldcnt == 0 && ret != EOF) \ 547 { \ 548 /* Fuzz returned data that wasn't in the old internal buffer */ \ 549 uint8_t ch = ret; \ 550 _zz_setpos(fd, oldpos); \ 551 _zz_fuzz(fd, &ch, 1); \ 552 ret = ch; \ 553 } \ 554 if (newpos > oldpos + oldcnt) \ 555 { \ 556 /* Fuzz the internal stream buffer */ \ 557 _zz_setpos(fd, newpos - get_stream_off(s)); \ 558 _zz_fuzz(fd, get_stream_ptr(s) - get_stream_off(s), \ 559 get_stream_cnt(s) + get_stream_off(s)); \ 560 } \ 561 _zz_setpos(fd, newpos); \ 595 562 if(ret == EOF) \ 596 563 debug("%s([%i]) = EOF", __func__, fd); \ … … 652 619 */ 653 620 654 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */655 # define FGETS_FUZZ(myfgets, myfgetc) \656 _zz_lock(fd); \657 ret = ORIG(myfgets)(s, size, stream); \658 _zz_unlock(fd);659 #else660 # define FGETS_FUZZ(myfgets, myfgetc) \661 if(size <= 0) \662 ret = NULL; \663 else if(size == 1) \664 s[0] = '\0'; \665 else \666 { \667 int i; \668 for(i = 0; i < size - 1; i++) \669 { \670 int ch; \671 _zz_lock(fd); \672 ch = ORIG(myfgetc)(stream); \673 _zz_unlock(fd); \674 if(ch == EOF) \675 { \676 s[i] = '\0'; \677 if(!i) \678 ret = NULL; \679 break; \680 } \681 s[i] = (char)(unsigned char)ch; \682 _zz_fuzz(fd, (uint8_t *)s + i, 1); /* rather inefficient */ \683 _zz_addpos(fd, 1); \684 if(s[i] == '\n') \685 { \686 s[i + 1] = '\0'; \687 break; \688 } \689 } \690 }691 #endif692 693 621 #define FGETS(myfgets, myfgetc) \ 694 622 do \ 695 623 { \ 624 int64_t oldpos, newpos; \ 625 int oldoff, oldcnt; \ 696 626 int fd; \ 697 627 ret = s; \ … … 701 631 if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \ 702 632 return ORIG(myfgets)(s, size, stream); \ 703 debug_stream("old", s); \ 704 _zz_setpos(fd, MYFTELL(stream)); \ 705 FGETS_FUZZ(myfgets, myfgetc) \ 633 debug_stream("old", stream); \ 634 oldpos = MYFTELL(stream); \ 635 oldoff = get_stream_off(stream); \ 636 oldcnt = get_stream_cnt(stream); \ 637 newpos = oldpos; \ 638 if(size <= 0) \ 639 ret = NULL; \ 640 else if(size == 1) \ 641 s[0] = '\0'; \ 642 else \ 643 { \ 644 int i; \ 645 for(i = 0; i < size - 1; i++) \ 646 { \ 647 int chr; \ 648 _zz_lock(fd); \ 649 chr = ORIG(myfgetc)(stream); \ 650 _zz_unlock(fd); \ 651 newpos = oldpos + 1; \ 652 if (oldcnt == 0 && chr != EOF) \ 653 { \ 654 /* Fuzz returned data that wasn't in the old buffer */ \ 655 uint8_t ch = chr; \ 656 _zz_setpos(fd, oldpos); \ 657 _zz_fuzz(fd, &ch, 1); \ 658 chr = ch; \ 659 } \ 660 if (newpos > oldpos + oldcnt) \ 661 { \ 662 /* Fuzz the internal stream buffer, if necessary */ \ 663 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 664 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 665 get_stream_cnt(stream) + get_stream_off(stream)); \ 666 } \ 667 oldpos = newpos; \ 668 oldoff = get_stream_off(stream); \ 669 oldcnt = get_stream_cnt(stream); \ 670 if(chr == EOF) \ 671 { \ 672 s[i] = '\0'; \ 673 if(!i) \ 674 ret = NULL; \ 675 break; \ 676 } \ 677 s[i] = (char)(unsigned char)chr; \ 678 if(s[i] == '\n') \ 679 { \ 680 s[i + 1] = '\0'; \ 681 break; \ 682 } \ 683 } \ 684 } \ 685 _zz_setpos(fd, newpos); \ 706 686 debug("%s(%p, %i, [%i]) = %p", __func__, s, size, fd, ret); \ 707 debug_stream("new", s ); \687 debug_stream("new", stream); \ 708 688 } while(0) 709 689 … … 726 706 int NEW(ungetc)(int c, FILE *stream) 727 707 { 728 int ret, fd;708 int oldpos, ret, fd; 729 709 730 710 LOADSYM(ungetc); … … 734 714 735 715 debug_stream("old", stream); 736 _zz_setpos(fd, MYFTELL(stream));716 oldpos = MYFTELL(stream); 737 717 _zz_lock(fd); 738 718 ret = ORIG(ungetc)(c, stream); 739 719 _zz_unlock(fd); 740 741 if(ret != EOF) 742 { 743 struct fuzz *fuzz = _zz_getfuzz(fd); 744 fuzz->uflag = 1; 745 fuzz->upos = _zz_getpos(fd) - 1; 746 fuzz->uchar = c; 747 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */ 748 #else 749 _zz_addpos(fd, -1); 750 #endif 751 } 720 _zz_setpos(fd, oldpos - 1); 752 721 753 722 if(ret == EOF) … … 788 757 #define GETDELIM(mygetdelim, delim, need_delim) \ 789 758 do { \ 759 int64_t oldpos, newpos; \ 790 760 char *line; \ 791 761 ssize_t done, size; \ 792 int fd, already_fuzzed = 0, finished = 0; \ 762 int oldoff, oldcnt; \ 763 int fd, finished = 0; \ 793 764 LOADSYM(mygetdelim); \ 794 765 LOADSYM(getdelim); \ … … 796 767 fd = fileno(stream); \ 797 768 if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \ 798 { \ 799 ret = ORIG(getdelim)(lineptr, n, delim, stream); \ 800 break; \ 801 } \ 769 return ORIG(getdelim)(lineptr, n, delim, stream); \ 802 770 debug_stream("old", stream); \ 803 _zz_setpos(fd, MYFTELL(stream)); \ 771 oldpos = MYFTELL(stream); \ 772 oldoff = get_stream_off(stream); \ 773 oldcnt = get_stream_cnt(stream); \ 774 newpos = oldpos; \ 804 775 line = *lineptr; \ 805 776 size = line ? *n : 0; \ … … 807 778 for(;;) \ 808 779 { \ 809 int ch ; \780 int chr; \ 810 781 if(done >= size) /* highly inefficient but I don't care */ \ 811 782 line = realloc(line, size = done + 1); \ … … 818 789 } \ 819 790 _zz_lock(fd); \ 820 ch = ORIG(fgetc)(stream); \791 chr = ORIG(fgetc)(stream); \ 821 792 _zz_unlock(fd); \ 822 if(ch == EOF) \ 793 newpos = oldpos + 1; \ 794 if (oldcnt == 0 && chr != EOF) \ 795 { \ 796 /* Fuzz returned data that wasn't in the old buffer */ \ 797 uint8_t ch = chr; \ 798 _zz_setpos(fd, oldpos); \ 799 _zz_fuzz(fd, &ch, 1); \ 800 chr = ch; \ 801 } \ 802 if (newpos > oldpos + oldcnt) \ 803 { \ 804 /* Fuzz the internal stream buffer, if necessary */ \ 805 _zz_setpos(fd, newpos - get_stream_off(stream)); \ 806 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), \ 807 get_stream_cnt(stream) + get_stream_off(stream)); \ 808 } \ 809 oldpos = newpos; \ 810 oldoff = get_stream_off(stream); \ 811 oldcnt = get_stream_cnt(stream); \ 812 if(chr == EOF) \ 823 813 { \ 824 814 finished = 1; \ … … 827 817 else \ 828 818 { \ 829 unsigned char c = ch; \ 830 _zz_fuzz(fd, &c, 1); /* even more inefficient */ \ 819 unsigned char c = chr; \ 831 820 line[done++] = c; \ 832 _zz_addpos(fd, 1); \833 821 if(c == delim) \ 834 822 { \ … … 838 826 } \ 839 827 } \ 828 _zz_setpos(fd, newpos); \ 840 829 if(need_delim) \ 841 830 debug("%s(%p, %p, '%c', [%i]) = %li", __func__, \ … … 876 865 char *NEW(fgetln)(FILE *stream, size_t *len) 877 866 { 867 int64_t oldpos, newpos; 878 868 char *ret; 879 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */880 #else881 869 struct fuzz *fuzz; 882 870 size_t i, size; 883 #endif 884 int fd; 871 int oldoff, oldcnt, fd; 885 872 886 873 LOADSYM(fgetln); … … 891 878 892 879 debug_stream("old", stream); 893 #if defined HAVE_DARWIN_STDIO /* Don't fuzz or seek if we have __srefill() */ 894 _zz_lock(fd); 895 ret = ORIG(fgetln)(stream, len); 896 _zz_unlock(fd); 897 #else 898 _zz_setpos(fd, MYFTELL(stream)); 880 oldpos = MYFTELL(stream); 881 oldoff = get_stream_off(stream); 882 oldcnt = get_stream_cnt(stream); 883 newpos = oldpos; 884 899 885 fuzz = _zz_getfuzz(fd); 900 886 901 887 for(i = size = 0; ; /* i is incremented below */) 902 888 { 903 int ch ;889 int chr; 904 890 905 891 _zz_lock(fd); 906 ch = ORIG(fgetc)(stream);892 chr = ORIG(fgetc)(stream); 907 893 _zz_unlock(fd); 908 894 909 if(ch == EOF) 895 newpos = oldpos + 1; 896 if (oldcnt == 0 && chr != EOF) 897 { 898 /* Fuzz returned data that wasn't in the old buffer */ 899 uint8_t ch = chr; 900 _zz_setpos(fd, oldpos); 901 _zz_fuzz(fd, &ch, 1); 902 chr = ch; 903 } 904 if (newpos > oldpos + oldcnt) 905 { 906 /* Fuzz the internal stream buffer, if necessary */ 907 _zz_setpos(fd, newpos - get_stream_off(stream)); 908 _zz_fuzz(fd, get_stream_ptr(stream) - get_stream_off(stream), 909 get_stream_cnt(stream) + get_stream_off(stream)); 910 } 911 oldpos = newpos; 912 oldoff = get_stream_off(stream); 913 oldcnt = get_stream_cnt(stream); 914 915 if(chr == EOF) 910 916 break; 911 917 … … 913 919 fuzz->tmp = realloc(fuzz->tmp, (size += 80)); 914 920 915 fuzz->tmp[i] = (char)(unsigned char)ch; 916 _zz_fuzz(fd, (uint8_t *)fuzz->tmp + i, 1); /* rather inefficient */ 917 _zz_addpos(fd, 1); 921 fuzz->tmp[i] = (char)(unsigned char)chr; 918 922 919 923 if(fuzz->tmp[i++] == '\n') … … 923 927 *len = i; 924 928 ret = fuzz->tmp; 925 #endif926 929 927 930 debug("%s([%i], &%li) = %p", __func__, fd, (long int)*len, ret); … … 989 992 debug("%s([%i]) = %i", __func__, fd, ret); \ 990 993 else if (ret == EOF) \ 991 debug("%s([%i]) = EOF", __func__, fd , ret); \994 debug("%s([%i]) = EOF", __func__, fd); \ 992 995 else \ 993 996 debug("%s([%i]) = '%c'", __func__, fd, ret); \
Note: See TracChangeset
for help on using the changeset viewer.