-
Notifications
You must be signed in to change notification settings - Fork 1.9k
snappy: fix intermittent decompression failures for raw snappy data #11550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,8 @@ | |
|
|
||
| #include <snappy.h> | ||
|
|
||
| #include <string.h> | ||
|
|
||
| int flb_snappy_compress(char *in_data, size_t in_len, | ||
| char **out_data, size_t *out_len) | ||
| { | ||
|
|
@@ -139,7 +141,25 @@ int flb_snappy_uncompress_framed_data(char *in_data, size_t in_len, | |
| struct cfl_list chunks; | ||
| struct flb_snappy_data_chunk *chunk; | ||
|
|
||
| if (*((uint8_t *) in_data) != FLB_SNAPPY_FRAME_TYPE_STREAM_IDENTIFIER) { | ||
| /* | ||
| * Distinguish raw/block snappy from the framed/streaming format. | ||
| * | ||
| * The framed format always starts with a stream identifier frame: | ||
| * byte 0: 0xFF (stream identifier chunk type) | ||
| * bytes 1-3: 0x06 0x00 0x00 (length = 6, little-endian 24-bit) | ||
| * bytes 4-9: "sNaPpY" | ||
| * | ||
| * A single first-byte check is insufficient because raw snappy data | ||
| * encodes the uncompressed length as a varint whose first byte can | ||
| * be 0xFF (e.g. when the uncompressed size mod 128 == 127 and >= 128). | ||
| * Checking the full 10-byte header avoids this false positive. | ||
| */ | ||
| if (in_len < 10 || | ||
| *((uint8_t *) &in_data[0]) != 0xFF || | ||
| *((uint8_t *) &in_data[1]) != 0x06 || | ||
| *((uint8_t *) &in_data[2]) != 0x00 || | ||
| *((uint8_t *) &in_data[3]) != 0x00 || | ||
| memcmp(&in_data[4], FLB_SNAPPY_STREAM_IDENTIFIER_STRING, 6) != 0) { | ||
| return flb_snappy_uncompress(in_data, in_len, out_data, out_len); | ||
| } | ||
|
|
||
|
|
@@ -282,7 +302,6 @@ int flb_snappy_uncompress_framed_data(char *in_data, size_t in_len, | |
| } | ||
|
|
||
| aggregated_data_buffer = NULL; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Removing the Useful? React with 👍 / 👎.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have updated commit to take into account this case. This is completely fair point, we discussed internally but this review confirmed it. |
||
| aggregated_data_length = 0; | ||
|
|
||
| if (compressed_chunk_count == 1 && | ||
| uncompressed_chunk_count == 0 && | ||
|
|
@@ -302,7 +321,7 @@ int flb_snappy_uncompress_framed_data(char *in_data, size_t in_len, | |
| flb_free(chunk); | ||
| } | ||
| else { | ||
| if (aggregated_data_length > 0) { | ||
| if (aggregated_data_length > 0 && result == 0) { | ||
| aggregated_data_buffer = flb_calloc(aggregated_data_length, | ||
| sizeof(char)); | ||
|
|
||
|
|
@@ -337,6 +356,12 @@ int flb_snappy_uncompress_framed_data(char *in_data, size_t in_len, | |
| } | ||
| } | ||
|
|
||
| if (result != 0) { | ||
| flb_free(aggregated_data_buffer); | ||
| aggregated_data_buffer = NULL; | ||
| aggregated_data_offset = 0; | ||
| } | ||
|
|
||
| *out_data = (char *) aggregated_data_buffer; | ||
| *out_len = aggregated_data_offset; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.