diff options
| author | Leo Constantinides <35425444+leoconst@users.noreply.github.com> | 2023-02-13 13:44:34 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-13 15:44:34 +0200 |
| commit | 25d6b8c1f1d5dc532c2bb68057d90751895aea68 (patch) | |
| tree | 1579a905d7320cd67bf99524ddef525b161518df /lib/std/json.zig | |
| parent | f62e3b8c0dd232bddb559405b00c1c1c4815f359 (diff) | |
| download | zig-25d6b8c1f1d5dc532c2bb68057d90751895aea68.tar.gz zig-25d6b8c1f1d5dc532c2bb68057d90751895aea68.zip | |
std: support deserialising JSON strings containing escape seqences into sentinel slice
Diffstat (limited to 'lib/std/json.zig')
| -rw-r--r-- | lib/std/json.zig | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/std/json.zig b/lib/std/json.zig index 92afeead90..ae8c4678a8 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1678,19 +1678,16 @@ fn parseInternal( if (ptrInfo.child != u8) return error.UnexpectedToken; const source_slice = stringToken.slice(tokens.slice, tokens.i - 1); const len = stringToken.decodedLength(); - const output = try allocator.alloc(u8, len + @boolToInt(ptrInfo.sentinel != null)); + const output = if (ptrInfo.sentinel) |sentinel_ptr| + try allocator.allocSentinel(u8, len, @ptrCast(*const u8, sentinel_ptr).*) + else + try allocator.alloc(u8, len); errdefer allocator.free(output); switch (stringToken.escapes) { .None => mem.copy(u8, output, source_slice), .Some => try unescapeValidString(output, source_slice), } - if (ptrInfo.sentinel) |some| { - const char = @ptrCast(*const u8, some).*; - output[len] = char; - return output[0..len :char]; - } - return output; }, else => return error.UnexpectedToken, @@ -2684,3 +2681,16 @@ test "encodesTo" { try testing.expectEqual(true, encodesTo("😂", "\\ud83d\\ude02")); try testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02")); } + +test "issue 14600" { + const json = "\"\\n\""; + var token_stream = std.json.TokenStream.init(json); + const options = ParseOptions{ .allocator = std.testing.allocator }; + + // Pre-fix, this line would panic: + const result = try std.json.parse([:0]const u8, &token_stream, options); + defer std.json.parseFree([:0]const u8, result, options); + + // Double-check that we're getting the right result + try testing.expect(mem.eql(u8, result, "\n")); +} |
