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 zcmZ?s5AtPTkWcdTaq@NY^>ATeU=aEL|Nnmm1_lOZ2F3;k1|1Vd2Zj^QzK#J53=9%y z&YWRjVEF(4e@92hDkX-yp$zYKGca^8I6L~fGcYi)Ffa-*xCD4AfY~MtI!^vBkqiv- zOg9-A85(|fFsyjJis9AocZ~o3qw{Yvd}Cm6`0c_R5*m8-_g#j+-~M9=++_I2z^tI8 zwCMRN=3TpY|Ni$MoqvfO8dgI$8c2fKt(P*C)DD06su zc|F)AD14Ah21l6uV_>NN{GZ{^8wO?uj*f=U3=B+PVWER5@{fVR;WGmR%NtOPfr7;m zJ)95%2(|whm{Gz9lMgfX3j-@CoI(TtB0>&b1Ys_EIzs0oR6>(e0DAgD2q4s=rz=c8 zl50Wf4eVN2iep6+L70o4*3kI~mERZ`M#Gi?JtV(ih#*1?JuK1r2$iE@`-TBCBr!!0 zA%-57=zN6A(Xbs2TX^jNs?QO{D@Fl~NHv({D|$UYTHb=%7_d;l2ucir(Xa)zxe%d% z-Y!7rBUEApC58Y(?P$6MwFA+^5}l6-FN~nX5J0FM4cpPMh14XNeFgNs1gu;f?K^ 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; }