aboutsummaryrefslogtreecommitdiff
path: root/lib/std/json.zig
diff options
context:
space:
mode:
authorLeo Constantinides <35425444+leoconst@users.noreply.github.com>2023-02-13 13:44:34 +0000
committerGitHub <noreply@github.com>2023-02-13 15:44:34 +0200
commit25d6b8c1f1d5dc532c2bb68057d90751895aea68 (patch)
tree1579a905d7320cd67bf99524ddef525b161518df /lib/std/json.zig
parentf62e3b8c0dd232bddb559405b00c1c1c4815f359 (diff)
downloadzig-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.zig24
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"));
+}