:: commit aae16d107f804f69000c09cd92027a140968cc9d

Kamila Szewczyk <kspalaiologos@gmail.com> — 2023-03-19 13:25

parents: 4a9d2c5d08

safety checks for decoding/testing when the buffer size and block size are inconsistent, tentative CRC32 version for BE systems (needs further verification on SPARC?)

diff --git a/src/libbz3.c b/src/libbz3.c
index 3a4bc0f..313dfe6 100644
--- a/src/libbz3.c
+++ b/src/libbz3.c
@@ -61,8 +61,15 @@ static const u32 crc32Table[256] = {
 };
 
 static u32 crc32sum(u32 crc, u8 * RESTRICT buf, size_t size) {
-    while (size--) crc = crc32Table[(crc ^ *(buf++)) & 0xff] ^ (crc >> 8);
-    return crc;
+    // Test endianness. The code needs to be different for LE and BE systems.
+    u32 test = 1;
+    if (*(u8 *) &test) {
+        while (size--) crc = crc32Table[(crc ^ *(buf++)) & 0xff] ^ (crc >> 8);
+        return crc;
+    } else {
+        while (size--) crc = crc32Table[((crc >> 24) ^ *(buf++)) & 0xff] ^ (crc << 8);
+        return crc;
+    }
 }
 
 /* LZP code. These constants were manually tuned to give the best compression ratio while using relatively
diff --git a/src/main.c b/src/main.c
index 712c510..f993b13 100644
--- a/src/main.c
+++ b/src/main.c
@@ -242,6 +242,10 @@ static int process(FILE * input_des, FILE * output_des, int mode, int block_size
                 new_size = read_neutral_s32(byteswap_buf);
                 xread_noeof(&byteswap_buf, 1, 4, input_des);
                 old_size = read_neutral_s32(byteswap_buf);
+                if(old_size > block_size + 31) {
+                    fprintf(stderr, "Failed to decode a block: Inconsistent headers.\n");
+                    return 1;
+                }
                 xread_noeof(buffer, 1, new_size, input_des);
                 bytes_read += 8 + new_size;
                 if (bz3_decode_block(state, buffer, new_size, old_size) == -1) {
@@ -259,6 +263,10 @@ static int process(FILE * input_des, FILE * output_des, int mode, int block_size
                 new_size = read_neutral_s32(byteswap_buf);
                 xread_noeof(&byteswap_buf, 1, 4, input_des);
                 old_size = read_neutral_s32(byteswap_buf);
+                if(old_size > block_size + 31) {
+                    fprintf(stderr, "Failed to decode a block: Inconsistent headers.\n");
+                    return 1;
+                }
                 xread_noeof(buffer, 1, new_size, input_des);
                 bytes_read += 8 + new_size;
                 if (bz3_decode_block(state, buffer, new_size, old_size) == -1) {
@@ -332,6 +340,10 @@ static int process(FILE * input_des, FILE * output_des, int mode, int block_size
                     sizes[i] = read_neutral_s32(byteswap_buf);
                     xread_noeof(&byteswap_buf, 1, 4, input_des);
                     old_sizes[i] = read_neutral_s32(byteswap_buf);
+                    if(old_sizes[i] > block_size + 31) {
+                        fprintf(stderr, "Failed to decode a block: Inconsistent headers.\n");
+                        return 1;
+                    }
                     xread_noeof(buffers[i], 1, sizes[i], input_des);
                     bytes_read += 8 + sizes[i];
                 }
@@ -356,6 +368,10 @@ static int process(FILE * input_des, FILE * output_des, int mode, int block_size
                     sizes[i] = read_neutral_s32(byteswap_buf);
                     xread_noeof(&byteswap_buf, 1, 4, input_des);
                     old_sizes[i] = read_neutral_s32(byteswap_buf);
+                    if(old_sizes[i] > block_size + 31) {
+                        fprintf(stderr, "Failed to decode a block: Inconsistent headers.\n");
+                        return 1;
+                    }
                     xread_noeof(buffers[i], 1, sizes[i], input_des);
                     bytes_read += 8 + sizes[i];
                 }
@@ -691,6 +707,9 @@ int main(int argc, char * argv[]) {
     output_des = mode != MODE_TEST ? open_output(output, force) : NULL;
     input_des = open_input(input);
 
+    if(output != f2)
+        free(output);
+
     int r = process(input_des, output_des, mode, block_size, workers, verbose, input);
 
     fclose(input_des);
tab: 248 wrap: offon