From ae6c39e501950edb2890a2965dc60c2fe104c70b Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Mon, 30 Oct 2023 16:18:12 +0000 Subject: [PATCH] LibGfx/ILBM: Ensure decompressed body chunk data is the correct length --- Tests/LibGfx/TestImageDecoder.cpp | 1 + .../ilbm/incorrect-uncompressed-size.iff | Bin 0 -> 8042 bytes .../Libraries/LibGfx/ImageFormats/ILBMLoader.cpp | 12 +++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Tests/LibGfx/test-inputs/ilbm/incorrect-uncompressed-size.iff diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index f800ae0316..deeb1439a0 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -154,6 +154,7 @@ TEST_CASE(test_ilbm_malformed_header) TEST_CASE(test_ilbm_malformed_frame) { Array test_inputs = { + TEST_INPUT("ilbm/incorrect-uncompressed-size.iff"sv), TEST_INPUT("ilbm/missing-body-chunk.iff"sv) }; diff --git a/Tests/LibGfx/test-inputs/ilbm/incorrect-uncompressed-size.iff b/Tests/LibGfx/test-inputs/ilbm/incorrect-uncompressed-size.iff new file mode 100644 index 0000000000000000000000000000000000000000..80e47cf43a9fdff5af3dafbfe48149f6c887e49c GIT binary patch literal 8042 zcmeHMJ#X4j6g|d7Vg#v?x)ph>81n;w(2q#9fGAd#Axr;5#TZ5_KO<8`rT&0==-Pp` z0|V+-#289l*?ky_0`kS@$r4{Ucc_2hQNytC-1spH+97W4p uncompress_byte_run(ReadonlyBytes data, ILBMLoadingCo auto length = data.size(); dbgln_if(ILBM_DEBUG, "uncompress_byte_run pitch={} size={}", context.pitch, data.size()); - auto plane_data = TRY(ByteBuffer::create_uninitialized(context.pitch * context.bm_header.height * context.bm_header.planes)); + size_t plane_data_size = context.pitch * context.bm_header.height * context.bm_header.planes; + + // The maximum run length of this compression method is 127 bytes, so the uncompressed size + // cannot be more than 127 times the size of the chunk we are decompressing. + if (plane_data_size > NumericLimits::max() || ceil_div(plane_data_size, 127ul) > length) + return Error::from_string_literal("Uncompressed data size too large"); + + auto plane_data = TRY(ByteBuffer::create_uninitialized(plane_data_size)); u32 index = 0; u32 read_bytes = 0; @@ -197,6 +204,9 @@ static ErrorOr uncompress_byte_run(ReadonlyBytes data, ILBMLoadingCo } } + if (index != plane_data_size) + return Error::from_string_literal("Unexpected end of chunk while decompressing data"); + return plane_data; }