| ... | @@ -1678,19 +1678,16 @@ fn parseInternal( | ... | @@ -1678,19 +1678,16 @@ fn parseInternal( |
| 1678 | if (ptrInfo.child != u8) return error.UnexpectedToken; | 1678 | if (ptrInfo.child != u8) return error.UnexpectedToken; |
| 1679 | const source_slice = stringToken.slice(tokens.slice, tokens.i - 1); | 1679 | const source_slice = stringToken.slice(tokens.slice, tokens.i - 1); |
| 1680 | const len = stringToken.decodedLength(); | 1680 | const len = stringToken.decodedLength(); |
| 1681 | const output = try allocator.alloc(u8, len + @boolToInt(ptrInfo.sentinel != null)); | 1681 | const output = if (ptrInfo.sentinel) |sentinel_ptr| |
| | 1682 | try allocator.allocSentinel(u8, len, @ptrCast(*const u8, sentinel_ptr).*) |
| | 1683 | else |
| | 1684 | try allocator.alloc(u8, len); |
| 1682 | errdefer allocator.free(output); | 1685 | errdefer allocator.free(output); |
| 1683 | switch (stringToken.escapes) { | 1686 | switch (stringToken.escapes) { |
| 1684 | .None => mem.copy(u8, output, source_slice), | 1687 | .None => mem.copy(u8, output, source_slice), |
| 1685 | .Some => try unescapeValidString(output, source_slice), | 1688 | .Some => try unescapeValidString(output, source_slice), |
| 1686 | } | 1689 | } |
| 1687 | | 1690 | |
| 1688 | if (ptrInfo.sentinel) |some| { | | |
| 1689 | const char = @ptrCast(*const u8, some).*; | | |
| 1690 | output[len] = char; | | |
| 1691 | return output[0..len :char]; | | |
| 1692 | } | | |
| 1693 | | | |
| 1694 | return output; | 1691 | return output; |
| 1695 | }, | 1692 | }, |
| 1696 | else => return error.UnexpectedToken, | 1693 | else => return error.UnexpectedToken, |
| ... | @@ -2684,3 +2681,16 @@ test "encodesTo" { | ... | @@ -2684,3 +2681,16 @@ test "encodesTo" { |
| 2684 | try testing.expectEqual(true, encodesTo("😂", "\\ud83d\\ude02")); | 2681 | try testing.expectEqual(true, encodesTo("😂", "\\ud83d\\ude02")); |
| 2685 | try testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02")); | 2682 | try testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02")); |
| 2686 | } | 2683 | } |
| | 2684 | |
| | 2685 | test "issue 14600" { |
| | 2686 | const json = "\"\\n\""; |
| | 2687 | var token_stream = std.json.TokenStream.init(json); |
| | 2688 | const options = ParseOptions{ .allocator = std.testing.allocator }; |
| | 2689 | |
| | 2690 | // Pre-fix, this line would panic: |
| | 2691 | const result = try std.json.parse([:0]const u8, &token_stream, options); |
| | 2692 | defer std.json.parseFree([:0]const u8, result, options); |
| | 2693 | |
| | 2694 | // Double-check that we're getting the right result |
| | 2695 | try testing.expect(mem.eql(u8, result, "\n")); |
| | 2696 | } |