Commit 4c11684184

Jon-Eric Cook <joneric.cook@gmail.com>
2023-01-28 17:26:36
std.json: check output and source lengths in `std.json`
1 parent f68d3c6
Changed files (2)
lib
lib/std/json/test.zig
@@ -2238,6 +2238,12 @@ test "parse into struct with no fields" {
     try testing.expectEqual(T{}, try parse(T, &ts, ParseOptions{}));
 }
 
+test "parse into struct where destination and source lengths mismatch" {
+    const T = struct { a: [2]u8 };
+    var ts = TokenStream.init("{\"a\": \"bbb\"}");
+    try testing.expectError(error.LengthMismatch, parse(T, &ts, ParseOptions{}));
+}
+
 test "parse into struct with misc fields" {
     @setEvalBranchQuota(10000);
     const options = ParseOptions{ .allocator = testing.allocator };
lib/std/json.zig
@@ -1384,7 +1384,7 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ
             return errors;
         },
         .Array => |arrayInfo| {
-            return error{ UnexpectedEndOfJson, UnexpectedToken } || TokenStream.Error ||
+            return error{ UnexpectedEndOfJson, UnexpectedToken, LengthMismatch } || TokenStream.Error ||
                 UnescapeValidStringError ||
                 ParseInternalErrorImpl(arrayInfo.child, inferred_types ++ [_]type{T});
         },
@@ -1625,6 +1625,7 @@ fn parseInternal(
                     if (arrayInfo.child != u8) return error.UnexpectedToken;
                     var r: T = undefined;
                     const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
+                    if (r.len != stringToken.decodedLength()) return error.LengthMismatch;
                     switch (stringToken.escapes) {
                         .None => mem.copy(u8, &r, source_slice),
                         .Some => try unescapeValidString(&r, source_slice),