@@ -125,6 +125,50 @@ test "PackerIO: corrupted length field" {
125125 }
126126}
127127
128+ test "PackerIO: truncated array cleanup" {
129+ if (! has_new_io ) return error .SkipZigTest ;
130+
131+ // Test that truncated array data is properly cleaned up on error
132+ // This demonstrates the benefit of errdefer cleanupParseStack
133+ var buffer : [50 ]u8 = undefined ;
134+ var input = if (builtin .zig_version .minor == 14 )
135+ std .ArrayList (u8 ).init (allocator )
136+ else
137+ std .ArrayList (u8 ){};
138+ defer if (builtin .zig_version .minor == 14 ) input .deinit () else input .deinit (allocator );
139+
140+ // Create array header for 3 elements (0x93)
141+ if (builtin .zig_version .minor == 14 ) {
142+ try input .append (0x93 ); // fixarray with 3 elements
143+ try input .append (0x01 ); // first element: uint 1
144+ try input .append (0x02 ); // second element: uint 2
145+ // Missing third element - truncated!
146+ } else {
147+ try input .append (allocator , 0x93 );
148+ try input .append (allocator , 0x01 );
149+ try input .append (allocator , 0x02 );
150+ }
151+
152+ @memcpy (buffer [0.. input .items .len ], input .items );
153+
154+ var writer = std .Io .Writer .fixed (& buffer );
155+ var reader = std .Io .Reader .fixed (buffer [0.. input .items .len ]);
156+
157+ var packer = msgpack .PackerIO .init (& reader , & writer );
158+
159+ // Should fail due to truncated data (missing third element)
160+ const result = packer .read (allocator );
161+ if (result ) | payload | {
162+ payload .free (allocator );
163+ try expect (false ); // Should not succeed with truncated array
164+ } else | err | {
165+ // Expected error - truncated array cannot be fully read
166+ try expect (err == msgpack .MsgPackError .TypeMarkerReading or
167+ err == msgpack .MsgPackError .DataReading or
168+ err == error .EndOfStream );
169+ }
170+ }
171+
128172test "PackerIO: multiple payloads with error recovery" {
129173 if (! has_new_io ) return error .SkipZigTest ;
130174
0 commit comments