diff --git a/FrontEnd/Lib/flate_test.cw b/FrontEnd/Lib/flate_test.cw index 6ad0cce6..fab52c40 100644 --- a/FrontEnd/Lib/flate_test.cw +++ b/FrontEnd/Lib/flate_test.cw @@ -2,53 +2,77 @@ (import test) (import flate) (import bitstream) +(import fmt) -(fun test_inflate_generic_failure [] void : - (let @mut @ref out auto (array_val 1024 u8 [0])) - @doc "sub test: " - (block _ : - @doc "missing next block after final uncompressed block" - (let @ref data auto (array_val 5 u8 [ 0x00 0x00 0x00 0xff 0xff ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::TruncationError)) - (block _ : - @doc "invalid block 11" - (let @ref data auto (array_val 1 u8 [ 0x07 ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::CorruptionError)) +(defrec TestCase : + (field description (slice u8)) + (field input (slice u8)) + (field expected_result (union [uint flate::CorruptionError flate::NoSpaceError flate::TruncationError])) + (field expected_output (slice u8)) + (field output (slice @mut u8)) ) -(fun test_inflate_uncompressed_failure [] void : - (let @mut @ref out auto (array_val 1 u8 [0])) - (block _ : - @doc "truncation" - (let @ref data auto (array_val 1 u8 [ 0x01 ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::TruncationError)) - (block _ : - @doc "truncated checksum" - (let @ref data auto (array_val 4 u8 [ 0x01 0x00 0x00 0xff ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::TruncationError)) - (block _ : - @doc "bad checksum" - (let @ref data auto (array_val 5 u8 [ 0x01 0x00 0x00 0xee 0xee ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::CorruptionError)) +(global @mut large_output_buffer auto (array_val 1024 u8 [0])) - (block _ : - @doc "truncated data" - (let @ref data auto (array_val 5 u8 [ 0x01 0x00 0x00 0xee 0xee ])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::CorruptionError)) +(global @mut one_byte_output_buffer auto (array_val 1 u8 [0])) - (block _ : - @doc "writing past end" - (let @ref data auto (array_val 7 u8 [ 0x01 0x02 0x00 0xfd 0xff 00 00])) - (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val data)])) - (test::AssertIs! (flate::uncompress [ (& @mut bs) out ]) flate::NoSpaceError)) +(global AllTestCases auto (array_val 6 TestCase [ + (rec_val TestCase [ + "generic: missing next block after final uncompressed block" + (array_val 5 u8 [ 0x00 0x00 0x00 0xff 0xff ]) + flate::TruncationErrorVal + (array_val 0 u8 []) + large_output_buffer + ]) + (rec_val TestCase [ + "generic: invalid block 11" + (array_val 1 u8 [ 0x07 ]) + flate::CorruptionErrorVal + (array_val 0 u8 []) + large_output_buffer + ]) + (rec_val TestCase [ + "uncompressed: truncation" + (array_val 1 u8 [ 0x01 ]) + flate::TruncationErrorVal + (array_val 0 u8 []) + large_output_buffer + ]) + (rec_val TestCase [ + "uncompressed: truncation checksum" + (array_val 4 u8 [0x01 0x00 0x00 0xff ]) + flate::TruncationErrorVal + (array_val 0 u8 []) + large_output_buffer + ]) + (rec_val TestCase [ + "uncompressed: bad checksum" + (array_val 5 u8 [ 0x01 0x00 0x00 0xee 0xee ]) + flate::CorruptionErrorVal + (array_val 0 u8 []) + large_output_buffer + ]) + (rec_val TestCase [ + "uncompressed: writing past end" + (array_val 7 u8 [ 0x01 0x02 0x00 0xfd 0xff 0x00 0x00 ]) + flate::NoSpaceErrorVal + (array_val 0 u8 []) + one_byte_output_buffer + ]) +])) + +(fun test_all [] void : + (for i 0 (len AllTestCases) 1 : + (let tc (ptr TestCase) (& (at AllTestCases i))) + (fmt::print! ["TEST - " (-> tc description) "\n"]) + (let @ref @mut bs auto (rec_val bitstream::Stream32 [(field_val (-> tc input))])) + (let res auto (flate::uncompress [ (& @mut bs) (-> tc output) ])) + (test::AssertEq! (uniontypetag res) (uniontypetag (-> tc expected_result))) + + ) ) + (fun test_inflate_uncompressed_success [] void : (let @mut @ref out auto (array_val 1024 u8 [0])) (block _ : @@ -136,9 +160,7 @@ ) (fun @cdecl main [(param argc s32) (param argv (ptr (ptr u8)))] s32 : - (stmt (test_inflate_generic_failure [])) @doc "uncompressed" - (stmt (test_inflate_uncompressed_failure [])) (stmt (test_inflate_uncompressed_success [])) @doc "fixed huffman" @@ -148,6 +170,8 @@ @doc "dynamic huffman" (stmt (test_inflate_dynamic_huffman_success [])) + (stmt (test_all [])) + @doc "test end" (test::Success!) (return 0)) diff --git a/FrontEnd/symbolize.py b/FrontEnd/symbolize.py index 5312db5b..88f8daf9 100755 --- a/FrontEnd/symbolize.py +++ b/FrontEnd/symbolize.py @@ -461,7 +461,9 @@ def IterateValArray(val_array: cwast.ValArray, width): curr_val += 1 yield curr_val, init curr_val += 1 - assert curr_val <= width + if curr_val > width: + cwast.CompilerError( + val_array.x_srcloc, f"Out of bounds array access at {curr_val}. Array size is {width}") while curr_val < width: yield curr_val, None curr_val += 1