@@ -18,8 +18,8 @@ local int gz_init(state)
18
18
int ret ;
19
19
z_streamp strm = & (state -> strm );
20
20
21
- /* allocate input buffer */
22
- state -> in = (unsigned char * )malloc (state -> want );
21
+ /* allocate input buffer (double size for gzprintf) */
22
+ state -> in = (unsigned char * )malloc (state -> want << 1 );
23
23
if (state -> in == NULL ) {
24
24
gz_error (state , Z_MEM_ERROR , "out of memory" );
25
25
return -1 ;
@@ -309,7 +309,8 @@ int ZEXPORT gzputs(file, str)
309
309
/* -- see zlib.h -- */
310
310
int ZEXPORTVA gzvprintf (gzFile file , const char * format , va_list va )
311
311
{
312
- int size , len ;
312
+ unsigned len , left ;
313
+ char * next ;
313
314
gz_statep state ;
314
315
z_streamp strm ;
315
316
@@ -334,39 +335,47 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
334
335
return 0 ;
335
336
}
336
337
337
- /* consume whatever's left in the input buffer */
338
- if ( strm -> avail_in && gz_comp ( state , Z_NO_FLUSH ) == -1 )
339
- return 0 ;
340
-
341
- /* do the printf() into the input buffer, put length in len */
342
- size = (int )( state -> size );
343
- state -> in [ size - 1 ] = 0 ;
338
+ /* do the printf() into the input buffer, put length in len -- the input
339
+ buffer is double-sized just for this function, so there is guaranteed to
340
+ be state->size bytes available after the current contents */
341
+ if ( strm -> avail_in == 0 )
342
+ strm -> next_in = state -> in ;
343
+ next = (char * )( strm -> next_in + strm -> avail_in );
344
+ next [ state -> size - 1 ] = 0 ;
344
345
#ifdef NO_vsnprintf
345
346
# ifdef HAS_vsprintf_void
346
- (void )vsprintf (( char * )( state -> in ) , format , va );
347
- for (len = 0 ; len < size ; len ++ )
348
- if (state -> in [len ] == 0 ) break ;
347
+ (void )vsprintf (next , format , va );
348
+ for (len = 0 ; len < state -> size ; len ++ )
349
+ if (next [len ] == 0 ) break ;
349
350
# else
350
- len = vsprintf (( char * )( state -> in ) , format , va );
351
+ len = vsprintf (next , format , va );
351
352
# endif
352
353
#else
353
354
# ifdef HAS_vsnprintf_void
354
- (void )vsnprintf (( char * )( state -> in ), size , format , va );
355
- len = strlen (( char * )( state -> in ) );
355
+ (void )vsnprintf (next , state -> size , format , va );
356
+ len = strlen (next );
356
357
# else
357
- len = vsnprintf (( char * )( state -> in ), size , format , va );
358
+ len = vsnprintf (next , state -> size , format , va );
358
359
# endif
359
360
#endif
360
361
361
362
/* check that printf() results fit in buffer */
362
- if (len <= 0 || len >= ( int ) size || state -> in [ size - 1 ] != 0 )
363
+ if (len == 0 || len >= state -> size || next [ state -> size - 1 ] != 0 )
363
364
return 0 ;
364
365
365
- /* update buffer and position, defer compression until needed */
366
- strm -> avail_in = (unsigned )len ;
367
- strm -> next_in = state -> in ;
366
+ /* update buffer and position, compress first half if past that */
367
+ strm -> avail_in += len ;
368
368
state -> x .pos += len ;
369
- return len ;
369
+ if (strm -> avail_in >= state -> size ) {
370
+ left = strm -> avail_in - state -> size ;
371
+ strm -> avail_in = state -> size ;
372
+ if (gz_comp (state , Z_NO_FLUSH ) == -1 )
373
+ return 0 ;
374
+ memcpy (state -> in , state -> in + state -> size , left );
375
+ strm -> next_in = state -> in ;
376
+ strm -> avail_in = left ;
377
+ }
378
+ return (int )len ;
370
379
}
371
380
372
381
int ZEXPORTVA gzprintf (gzFile file , const char * format , ...)
@@ -390,7 +399,8 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
390
399
int a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ,
391
400
a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 ;
392
401
{
393
- int size , len ;
402
+ unsigned len , left ;
403
+ char * next ;
394
404
gz_statep state ;
395
405
z_streamp strm ;
396
406
@@ -419,44 +429,52 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
419
429
return 0 ;
420
430
}
421
431
422
- /* consume whatever's left in the input buffer */
423
- if ( strm -> avail_in && gz_comp ( state , Z_NO_FLUSH ) == -1 )
424
- return 0 ;
425
-
426
- /* do the printf() into the input buffer, put length in len */
427
- size = (int )( state -> size );
428
- state -> in [ size - 1 ] = 0 ;
432
+ /* do the printf() into the input buffer, put length in len -- the input
433
+ buffer is double-sized just for this function, so there is guaranteed to
434
+ be state->size bytes available after the current contents */
435
+ if ( strm -> avail_in == 0 )
436
+ strm -> next_in = state -> in ;
437
+ next = (char * )( strm -> next_in + strm -> avail_in );
438
+ next [ state -> size - 1 ] = 0 ;
429
439
#ifdef NO_snprintf
430
440
# ifdef HAS_sprintf_void
431
- sprintf (( char * )( state -> in ) , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ,
432
- a9 , a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
441
+ sprintf (next , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 , a12 ,
442
+ a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
433
443
for (len = 0 ; len < size ; len ++ )
434
- if (state -> in [len ] == 0 ) break ;
444
+ if (next [len ] == 0 )
445
+ break ;
435
446
# else
436
- len = sprintf (( char * )( state -> in ) , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ,
437
- a9 , a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
447
+ len = sprintf (next , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ,
448
+ a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
438
449
# endif
439
450
#else
440
451
# ifdef HAS_snprintf_void
441
- snprintf (( char * )( state -> in ), size , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ,
442
- a9 , a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
443
- len = strlen (( char * )( state -> in ) );
452
+ snprintf (next , state -> size , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ,
453
+ a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
454
+ len = strlen (next );
444
455
# else
445
- len = snprintf ((char * )(state -> in ), size , format , a1 , a2 , a3 , a4 , a5 , a6 ,
446
- a7 , a8 , a9 , a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 ,
447
- a19 , a20 );
456
+ len = snprintf (next , state -> size , format , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ,
457
+ a9 , a10 , a11 , a12 , a13 , a14 , a15 , a16 , a17 , a18 , a19 , a20 );
448
458
# endif
449
459
#endif
450
460
451
461
/* check that printf() results fit in buffer */
452
- if (len <= 0 || len >= ( int ) size || state -> in [ size - 1 ] != 0 )
462
+ if (len == 0 || len >= state -> size || next [ state -> size - 1 ] != 0 )
453
463
return 0 ;
454
464
455
- /* update buffer and position, defer compression until needed */
456
- strm -> avail_in = (unsigned )len ;
457
- strm -> next_in = state -> in ;
465
+ /* update buffer and position, compress first half if past that */
466
+ strm -> avail_in += len ;
458
467
state -> x .pos += len ;
459
- return len ;
468
+ if (strm -> avail_in >= state -> size ) {
469
+ left = strm -> avail_in - state -> size ;
470
+ strm -> avail_in = state -> size ;
471
+ if (gz_comp (state , Z_NO_FLUSH ) == -1 )
472
+ return 0 ;
473
+ memcpy (state -> in , state -> in + state -> size , left );
474
+ strm -> next_in = state -> in ;
475
+ strm -> avail_in = left ;
476
+ }
477
+ return (int )len ;
460
478
}
461
479
462
480
#endif
0 commit comments