@@ -241,9 +241,8 @@ int flb_gzip_compress(void *in_data, size_t in_len,
241
241
return 0 ;
242
242
}
243
243
244
- /* Uncompress (inflate) GZip data */
245
- int flb_gzip_uncompress (void * in_data , size_t in_len ,
246
- void * * out_data , size_t * out_len )
244
+ int flb_gzip_uncompress_member (void * in_data , size_t in_len ,
245
+ void * * out_data , size_t * out_len )
247
246
{
248
247
int status ;
249
248
uint8_t * p ;
@@ -292,7 +291,7 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
292
291
if (flg & FEXTRA ) {
293
292
xlen = read_le16 (start );
294
293
if (xlen > in_len - 12 ) {
295
- flb_error ("[gzip] invalid gzip data" );
294
+ flb_error ("[gzip] invalid gzip data (FEXTRA) " );
296
295
return -1 ;
297
296
}
298
297
start += xlen + 2 ;
@@ -321,7 +320,7 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
321
320
/* Check header crc if present */
322
321
if (flg & FHCRC ) {
323
322
if (start - p > in_len - 2 ) {
324
- flb_error ("[gzip] invalid gzip data (FHRC )" );
323
+ flb_error ("[gzip] invalid gzip data (FHCRC )" );
325
324
return -1 ;
326
325
}
327
326
@@ -414,9 +413,74 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
414
413
return 0 ;
415
414
}
416
415
416
+ int flb_gzip_uncompress (void * in_data , size_t in_len ,
417
+ void * * out_data , size_t * out_len )
418
+ {
419
+ int i , ret ;
420
+ size_t * borders = NULL ;
421
+ size_t count = 0 ;
422
+ size_t total = 0 ;
423
+ size_t part_len = 0 ;
424
+ size_t out_len_local = 0 ;
425
+ void * out = NULL ;
426
+ void * final_buf = NULL ;
427
+
428
+ count = flb_gzip_count (in_data , in_len , NULL , 0 );
429
+ if (count == 0 ) {
430
+ flb_error ("[gzip] no valid gzip members found" );
431
+ return -1 ;
432
+ }
417
433
418
- /* Stateful gzip decompressor */
434
+ borders = flb_calloc (count + 1 , sizeof (size_t ));
435
+ if (!borders ) {
436
+ flb_errno ();
437
+ return -1 ;
438
+ }
439
+
440
+ ret = flb_gzip_count (in_data , in_len , & borders , count );
441
+ if (ret != count ) {
442
+ flb_free (borders );
443
+ return -1 ;
444
+ }
445
+
446
+ for (i = 0 ; i < count ; i ++ ) {
447
+ part_len = borders [i + 1 ] - borders [i ];
448
+ out = NULL ;
449
+ out_len_local = 0 ;
419
450
451
+ ret = flb_gzip_uncompress_member ((uint8_t * )in_data + borders [i ],
452
+ part_len , & out , & out_len_local );
453
+ if (ret != 0 ) {
454
+ flb_free (out );
455
+ flb_free (borders );
456
+ flb_free (final_buf );
457
+ return -1 ;
458
+ }
459
+
460
+ final_buf = flb_realloc (final_buf , total + out_len_local );
461
+ if (!final_buf ) {
462
+ flb_errno ();
463
+ flb_free (out );
464
+ flb_free (borders );
465
+ flb_errno ();
466
+ return -1 ;
467
+ }
468
+
469
+ memcpy ((uint8_t * ) final_buf + total , out , out_len_local );
470
+ total += out_len_local ;
471
+ flb_free (out );
472
+ }
473
+
474
+ flb_free (borders );
475
+
476
+ * out_data = final_buf ;
477
+ * out_len = total ;
478
+
479
+ return 0 ;
480
+ }
481
+
482
+
483
+ /* Stateful gzip decompressor */
420
484
static int flb_gzip_decompressor_process_header (
421
485
struct flb_decompression_context * context )
422
486
{
@@ -802,7 +866,7 @@ static int vaild_os_flag(const char data)
802
866
803
867
size_t flb_gzip_count (const char * data , size_t len , size_t * * out_borders , size_t border_count )
804
868
{
805
- int i ;
869
+ size_t i ;
806
870
size_t count = 0 ;
807
871
const uint8_t * p ;
808
872
size_t * borders = NULL ;
@@ -812,26 +876,27 @@ size_t flb_gzip_count(const char *data, size_t len, size_t **out_borders, size_t
812
876
}
813
877
814
878
p = (const uint8_t * ) data ;
815
- /* search other gzip starting bits and method. */
816
- for ( i = 2 ; i < len &&
817
- i + 9 <= len ; i ++ ) {
818
- /* A vaild gzip payloads are larger than 18 bytes. */
879
+
880
+ /* Search gzip starting bits and method */
881
+ for ( i = 0 ; i + 9 <= len ; i ++ ) {
882
+ /* A valid gzip payload must be at least 18 bytes long */
819
883
if (len - i < 18 ) {
820
884
break ;
821
885
}
822
886
823
887
if (p [i ] == 0x1F && p [i + 1 ] == 0x8B && p [i + 2 ] == 8 &&
824
888
vaild_os_flag (p [i + 9 ])) {
825
- if (out_borders != NULL ) {
889
+
890
+ if (out_borders != NULL && count < border_count ) {
826
891
borders [count ] = i ;
827
892
}
828
893
count ++ ;
829
894
}
830
895
}
831
896
832
- if ( out_borders != NULL && border_count >= count ) {
833
- /* The length of the last border refers to the original length. */
834
- borders [border_count ] = len ;
897
+ /* Append total length as the end boundary */
898
+ if ( out_borders != NULL && count > 0 && border_count >= count ) {
899
+ borders [count ] = len ;
835
900
}
836
901
837
902
return count ;
0 commit comments