@@ -241,9 +241,8 @@ int flb_gzip_compress(void *in_data, size_t in_len,
241241 return 0 ;
242242}
243243
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 )
247246{
248247 int status ;
249248 uint8_t * p ;
@@ -292,7 +291,7 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
292291 if (flg & FEXTRA ) {
293292 xlen = read_le16 (start );
294293 if (xlen > in_len - 12 ) {
295- flb_error ("[gzip] invalid gzip data" );
294+ flb_error ("[gzip] invalid gzip data (FEXTRA) " );
296295 return -1 ;
297296 }
298297 start += xlen + 2 ;
@@ -321,7 +320,7 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
321320 /* Check header crc if present */
322321 if (flg & FHCRC ) {
323322 if (start - p > in_len - 2 ) {
324- flb_error ("[gzip] invalid gzip data (FHRC )" );
323+ flb_error ("[gzip] invalid gzip data (FHCRC )" );
325324 return -1 ;
326325 }
327326
@@ -414,9 +413,74 @@ int flb_gzip_uncompress(void *in_data, size_t in_len,
414413 return 0 ;
415414}
416415
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+ }
417433
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 ;
419450
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 */
420484static int flb_gzip_decompressor_process_header (
421485 struct flb_decompression_context * context )
422486{
@@ -802,7 +866,7 @@ static int vaild_os_flag(const char data)
802866
803867size_t flb_gzip_count (const char * data , size_t len , size_t * * out_borders , size_t border_count )
804868{
805- int i ;
869+ size_t i ;
806870 size_t count = 0 ;
807871 const uint8_t * p ;
808872 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
812876 }
813877
814878 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 */
819883 if (len - i < 18 ) {
820884 break ;
821885 }
822886
823887 if (p [i ] == 0x1F && p [i + 1 ] == 0x8B && p [i + 2 ] == 8 &&
824888 vaild_os_flag (p [i + 9 ])) {
825- if (out_borders != NULL ) {
889+
890+ if (out_borders != NULL && count < border_count ) {
826891 borders [count ] = i ;
827892 }
828893 count ++ ;
829894 }
830895 }
831896
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 ;
835900 }
836901
837902 return count ;
0 commit comments