diff --git a/include/fluent-bit/flb_gzip.h b/include/fluent-bit/flb_gzip.h index 2efe9710d58..e52b04acc0e 100644 --- a/include/fluent-bit/flb_gzip.h +++ b/include/fluent-bit/flb_gzip.h @@ -38,5 +38,6 @@ int flb_gzip_decompressor_dispatch(struct flb_decompression_context *context, void *out_data, size_t *out_size); int flb_is_http_session_gzip_compressed(struct mk_http_session *session); +size_t flb_gzip_count(const char *data, size_t len, size_t **out_borders, size_t border_count); #endif diff --git a/plugins/in_forward/fw_prot.c b/plugins/in_forward/fw_prot.c index b48f79345bf..a4f5fa6a8b2 100644 --- a/plugins/in_forward/fw_prot.c +++ b/plugins/in_forward/fw_prot.c @@ -1495,11 +1495,16 @@ int fw_prot_process(struct flb_input_instance *ins, struct fw_conn *conn) size_t *gzip_borders = NULL; const size_t original_len = len; - gzip_payloads_count = flb_gzip_concatenated_count(data, len); + gzip_payloads_count = flb_gzip_count(data, len, NULL, 0); flb_plg_debug(ctx->ins, "concatenated gzip payload count is %zd", gzip_payloads_count); if (gzip_payloads_count > 0) { - if (flb_gzip_concatenated_borders(data, len, &gzip_borders, gzip_payloads_count) < 0) { + gzip_borders = (size_t *)flb_calloc(1, sizeof(size_t) * (gzip_payloads_count + 1)); + if (gzip_borders == NULL) { + flb_errno(); + return -1; + } + if (flb_gzip_count(data, len, &gzip_borders, gzip_payloads_count) < 0) { flb_plg_error(ctx->ins, "failed to traverse boundaries of concatenated gzip payloads"); return -1; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6819127163a..593e9865bc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,7 +60,6 @@ set(src flb_random.c flb_plugin.c flb_gzip.c - flb_gzip_concatenated.c flb_snappy.c flb_compression.c flb_http_common.c diff --git a/src/flb_gzip.c b/src/flb_gzip.c index a33b5558fec..3beea66b2cf 100644 --- a/src/flb_gzip.c +++ b/src/flb_gzip.c @@ -771,4 +771,68 @@ int flb_is_http_session_gzip_compressed(struct mk_http_session *session) } return gzip_compressed; -} \ No newline at end of file +} + +static int vaild_os_flag(const char data) +{ + uint8_t p; + + p = (uint8_t)data; + if (p == 0x00 || /* Fat Filesystem */ + p == 0x01 || /* Amiga */ + p == 0x02 || /* VMS */ + p == 0x03 || /* Unix */ + p == 0x04 || /* VM/CMS */ + p == 0x05 || /* Atari TOS */ + p == 0x06 || /* HPFS Filesystem (OS/2, NT) */ + p == 0x07 || /* Macintosh */ + p == 0x08 || /* Z-System */ + p == 0x09 || /* CP/M */ + p == 0x0a || /* TOPS-20 */ + p == 0x0b || /* NTFS filesystem (NT) */ + p == 0x0c || /* QDOS */ + p == 0x0d || /* Acorn RISCOS */ + p == 0xff) /* Unknown */ { + + return FLB_TRUE; + } + + return FLB_FALSE; +} + +size_t flb_gzip_count(const char *data, size_t len, size_t **out_borders, size_t border_count) +{ + int i; + size_t count = 0; + const uint8_t *p; + size_t *borders = NULL; + + if (out_borders != NULL) { + borders = *out_borders; + } + + p = (const uint8_t *) data; + /* search other gzip starting bits and method. */ + for (i = 2; i < len && + i + 9 <= len; i++) { + /* A vaild gzip payloads are larger than 18 bytes. */ + if (len - i < 18) { + break; + } + + if (p[i] == 0x1F && p[i+1] == 0x8B && p[i+2] == 8 && + vaild_os_flag(p[i+9])) { + if (out_borders != NULL) { + borders[count] = i; + } + count++; + } + } + + if (out_borders != NULL && border_count >= count) { + /* The length of the last border refers to the original length. */ + borders[border_count] = len; + } + + return count; +} diff --git a/src/flb_gzip_concatenated.c b/src/flb_gzip_concatenated.c deleted file mode 100644 index b5ba046225b..00000000000 --- a/src/flb_gzip_concatenated.c +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2015-2024 The Fluent Bit Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -static int vaild_os_flag(const char data) -{ - uint8_t p; - - p = (uint8_t)data; - if (p == 0x00 || /* Fat Filesystem */ - p == 0x01 || /* Amiga */ - p == 0x02 || /* VMS */ - p == 0x03 || /* Unix */ - p == 0x04 || /* VM/CMS */ - p == 0x05 || /* Atari TOS */ - p == 0x06 || /* HPFS Filesystem (OS/2, NT) */ - p == 0x07 || /* Macintosh */ - p == 0x08 || /* Z-System */ - p == 0x09 || /* CP/M */ - p == 0x0a || /* TOPS-20 */ - p == 0x0b || /* NTFS filesystem (NT) */ - p == 0x0c || /* QDOS */ - p == 0x0d || /* Acorn RISCOS */ - p == 0xff) /* Unknown */ { - - return FLB_TRUE; - } - - return FLB_FALSE; -} - -size_t flb_gzip_concatenated_count(const char *data, size_t len) -{ - int i; - size_t count = 0; - const uint8_t *p; - - p = (const uint8_t *) data; - - /* search other gzip starting bits and method. */ - for (i = 2; i < len && - i + 9 <= len; i++) { - /* A vaild gzip payloads are larger than 18 bytes. */ - if (len - i < 18) { - break; - } - - if (p[i] == 0x1F && p[i+1] == 0x8B && p[i+2] == 8 && - vaild_os_flag(p[i+9])) { - count++; - } - } - - return count; -} - -size_t flb_gzip_concatenated_borders(const char *data, size_t len, size_t **out_borders, size_t border_count) -{ - int i; - size_t count = 0; - const uint8_t *p; - size_t *borders = NULL; - - p = (const uint8_t *) data; - borders = (size_t *) flb_calloc(1, sizeof(size_t) * (border_count + 1)); - if (borders == NULL) { - flb_errno(); - return -1; - } - - /* search other gzip starting bits and method. */ - for (i = 2; i < len && - i + 9 <= len; i++) { - /* A vaild gzip payloads are larger than 18 bytes. */ - if (len - i < 18) { - break; - } - - if (p[i] == 0x1F && p[i+1] == 0x8B && p[i+2] == 8 && - vaild_os_flag(p[i+9])) { - borders[count] = i; - count++; - } - } - /* The length of the last border refers to the original length. */ - borders[border_count] = len; - - *out_borders = borders; - - return count; -} diff --git a/tests/internal/CMakeLists.txt b/tests/internal/CMakeLists.txt index fdc5dbcb8ca..7fe08ea0d8f 100644 --- a/tests/internal/CMakeLists.txt +++ b/tests/internal/CMakeLists.txt @@ -18,7 +18,6 @@ set(UNIT_TESTS_FILES http_client.c utils.c gzip.c - gzip_concatenated.c random.c config_map.c mp.c diff --git a/tests/internal/gzip.c b/tests/internal/gzip.c index a3f82341868..d9542d60778 100644 --- a/tests/internal/gzip.c +++ b/tests/internal/gzip.c @@ -40,7 +40,38 @@ void test_compress() flb_free(str); } +void test_not_overflow_for_concatenated_gzip() +{ + const char data[] = { + 0x00, 0x00, /* Initial padding */ + 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* First gzip header (valid header) */ + 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* Second gzip header (valid header) */ + 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* Third gzip header (valid header) */ + }; + size_t len = sizeof(data); + size_t *borders = NULL; + size_t border_count = 0; + size_t count = 0; + + /* Vaild gzip payloads have to 18 bytes lentgh at least. + * So, we get only 2 of vaild parts. + */ + border_count = flb_gzip_count(data, len, NULL, 0); + TEST_CHECK(border_count == 2); + + borders = (size_t *)flb_calloc(1, sizeof(size_t) * (border_count + 1)); + TEST_CHECK(borders != NULL); + + count = flb_gzip_count(data, len, &borders, border_count); + TEST_CHECK(count == 2); + + if (borders != NULL) { + free(borders); + } +} + TEST_LIST = { {"compress", test_compress}, + {"not_overflow", test_not_overflow_for_concatenated_gzip}, { 0 } }; diff --git a/tests/internal/gzip_concatenated.c b/tests/internal/gzip_concatenated.c deleted file mode 100644 index 1fd5d905a85..00000000000 --- a/tests/internal/gzip_concatenated.c +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include -#include - -#include "flb_tests_internal.h" - -void test_not_overflow_for_concatenated_gzip() -{ - const char data[] = { - 0x00, 0x00, /* Initial padding */ - 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* First gzip header (valid header) */ - 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* Second gzip header (valid header) */ - 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* Third gzip header (valid header) */ - }; - size_t len = sizeof(data); - size_t *borders; - size_t border_count = 2; - size_t count; - - /* Vaild gzip payloads have to 18 bytes lentgh at least. - * So, we get only 2 of vaild parts. - */ - count = flb_gzip_concatenated_count(data, len); - TEST_CHECK(count == 2); - - count = flb_gzip_concatenated_borders(data, len, &borders, border_count); - TEST_CHECK(count == 2); - - if (borders != NULL) { - free(borders); - } -} - -TEST_LIST = { - {"not_overflow", test_not_overflow_for_concatenated_gzip}, - { 0 } -};