From 4a90b5f843df4ccf5fdfbda2d255d9414f4a2ba2 Mon Sep 17 00:00:00 2001 From: "detail-app[bot]" <180357370+detail-app[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 02:03:44 +0000 Subject: [PATCH] fix: keep closing brackets when desyncing after a complete JSON array --- src/pipeline/frame_json_array.zig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/pipeline/frame_json_array.zig b/src/pipeline/frame_json_array.zig index 1a929860..61f33d98 100644 --- a/src/pipeline/frame_json_array.zig +++ b/src/pipeline/frame_json_array.zig @@ -147,6 +147,7 @@ pub const JsonArrayFramer = struct { const byte = chunk[i]; i += 1; if (isJsonWhitespace(byte)) continue; + try self.writeClose(out); try self.enterDesync(out, chunk[i - 1 ..]); return; }, @@ -469,6 +470,23 @@ test "truncated input flushes buffered bytes and closes best-effort" { try testing.expectEqualStrings("[{\"a\":1},{\"b\":]", got); } +test "trailing junk after complete array keeps closing brackets" { + for ([_]usize{ 1, 7, 4096 }) |chunk| { + var sink: TestSink = .{ .allocator = testing.allocator }; + defer sink.deinit(); + const got = try runChunked("[1]extra", chunk, 64, &sink); + defer testing.allocator.free(got); + try testing.expectEqualStrings("[1]extra", got); + } + for ([_]usize{ 1, 7, 4096 }) |chunk| { + var sink: TestSink = .{ .allocator = testing.allocator }; + defer sink.deinit(); + const got = try runChunked("[](", chunk, 64, &sink); + defer testing.allocator.free(got); + try testing.expectEqualStrings("[](", got); + } +} + test "stats are accounted" { const input = "[1,\"drop\",\"swap\",2]"; var sink: TestSink = .{ .allocator = testing.allocator };