Commit Graph
40 Commits
Author SHA1 Message Date
Jack Mordaunt 641844dae7 core/encoding/json: size the unquote buffer for replaced invalid UTF-8
unquote_string replaces each byte that is not valid UTF-8 with U+FFFD,
which is three bytes for one, but sized its buffer as len(s) + 2*UTF_MAX:
slack for a single replacement, not for one per invalid byte. A string
holding several ran the write cursor past the end, an out-of-range slice
under bounds checking and a memory-safety bug without it.

Count the invalid bytes in the remainder up front and size for them. The
escape sequences never grow their input, so they need no allowance.
2026-09-25 14:27:40 -03:00
user.name 6ccde7f80b bugfix: core/encoding/json leaks the key and value of a malformed object
parse_object_body allocates an object key, then may fail in parse_colon or
parse_value before that key is ever inserted into the object. Its cleanup defer
only walks `obj`, so a key that never got there is unreachable to it. The caller
cannot free it either -- a failed parse returns a nil Value -- so it leaks.

The same applies to the parsed element on the duplicate-key path, and to both on
the out-of-memory path.

JSON5 makes this reachable from ordinary malformed input, because an unquoted
ident is a legal key and anything other than a colon after it fails. Plain JSON
leaks it too, via a quoted key.

before, measured with a tracking allocator over 8 inputs x 2 specs:

	LEAK JSON5  colon fails after unquoted key   1 alloc / 7 bytes
	LEAK JSON   colon fails after quoted key     1 alloc / 2 bytes
	LEAK JSON5  colon fails after quoted key     1 alloc / 2 bytes
	LEAK JSON   value fails after key            1 alloc / 2 bytes
	LEAK JSON5  value fails after key            1 alloc / 2 bytes
	LEAK JSON   nested value fails               2 alloc / 4 bytes
	LEAK JSON5  nested value fails               2 alloc / 4 bytes
	LEAK JSON   deep nesting fails               3 alloc / 6 bytes
	LEAK JSON5  deep nesting fails               3 alloc / 6 bytes
	LEAK JSON   array element fails              1 alloc / 2 bytes
	LEAK JSON5  array element fails              1 alloc / 2 bytes
	total leaked allocations: 17

after, same probe:

	total leaked allocations: 0

The leak scales with nesting depth -- one orphaned key per enclosing object -- so
a service parsing untrusted JSON leaks a little on every malformed request.

The fix marks the key and the element as owned by the loop iteration until they
are stored, and frees them otherwise. The duplicate-key path loses its explicit
delete, which the same mechanism now covers.

Found via odinfmt, which reported a 7-byte leak in a downstream test that parses
`{ broken not json` to check that invalid input is rejected.

Regression test added to tests/core/encoding/json: it reports
`17 leaks and 0 bad frees` without this change and passes with it. The existing
11 tests pass unchanged under -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true.
2026-08-31 11:39:42 -07:00
gingerBill 9e713e2940 Update core:encoding/json to use proc groups and @(require_results) 2026-06-29 13:44:29 +01:00
Brad Lewis 87d58b9fb7 Handle invalid utf8 when parsing json 2026-05-10 16:23:26 +10:00
Sylphrena 6441fc09e0 Fix standard json parsing / unmarshalling issue for pure arrays 2025-12-29 15:35:34 +01:00
Neirokan 8cdf7ade48 encoding/json: clone unquoted strings 2025-11-06 19:24:58 +03:00
Jeroen van Rijn 601df0e8f7 Port tests\core\encoding\json 2024-06-02 14:47:08 -04:00
gingerBill 334e08c750 Update numerous package declaration names 2024-04-18 12:17:39 +01:00
gingerBill 5eef29290c Fix #3250 2024-03-06 11:49:17 +00:00
Rickard Andersson 931e0d4687 cleanup: remove unused import 2023-10-02 15:21:09 +03:00
Rickard Andersson cfa3765d50 fix: guard against empty key value in parse_object_body 2023-10-02 15:10:12 +03:00
Rickard Andersson 11e884aec5 docs: add note about checking for alloc error 2023-10-02 12:20:18 +03:00
Rickard Andersson 55a1ba710b fix: use runtime.map_insert to not overallocate 2023-10-02 11:59:37 +03:00
Rickard Andersson 0a8b266c71 fix(json): return .Out_Of_Memory when out of memory on parse
Previously this would silently simply not do anything and the object
would be empty/incomplete when parsed instead.
2023-10-02 11:50:16 +03:00
Abdelrahman Farid f1872f495a Fix bug with index increment in unquote_string 2023-09-19 22:19:05 +03:00
Laytan Laats 5d54b710e7 fix #2550 json encoding should use surrogate pairs per RFC7159 2023-05-22 17:22:33 +02:00
gingerBill f2ecda8fec Rename to SJSON for the Simplified JSON notation variant 2022-06-16 15:49:08 +01:00
Jeroen van Rijn a30b9b17b3 [json/unmarshal] Fix quoted strings. 2022-04-19 20:32:22 +02:00
Jeroen van Rijn 29b2c04766 Revert "Fix unmarshal for escaped strings."
This reverts commit 581255bf23.
2022-04-19 20:11:02 +02:00
Jeroen van Rijn 581255bf23 Fix unmarshal for escaped strings. 2022-04-19 20:04:38 +02:00
Daniel Gavin 5b074ceee5 Add json encoding test + fix enum not being set on success. 2021-11-07 14:35:52 +01:00
gingerBill d452758afc Improve MJSON handling 2021-09-28 15:01:11 +01:00
gingerBill c933054872 Support json.Specification.MJSON
https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html
2021-09-28 14:53:16 +01:00
gingerBill 6a271355a6 Add json.unmarshal 2021-09-25 17:47:45 +01:00
gingerBill 251da264ed Remove unneeded semicolons from the core library 2021-08-31 22:21:13 +01:00
gingerBill f293d7c997 Update package encoding/json for or_return 2021-08-15 23:11:15 +01:00
gingerBill db3501f61b [Breaking] Change the layout json.Value to be a union rather than a struct of a json.Pos and the union 2021-08-08 12:59:35 +01:00
gingerBill 86649e6b44 Core library clean up: Make range expressions more consistent and replace uses of .. with ..= 2021-06-14 11:15:25 +01:00
jockus 195dbd658d Added option to parse number as integer, disabled by default 2020-09-15 11:39:34 +01:00
gingerBill 5fa54fd2cc Commit fix 2020-06-16 16:07:44 +01:00
gingerBill e8f2fb58d9 Fix strconv.parse_ usage across other packages 2020-05-09 11:54:36 +01:00
gingerBill d1c9fd4e01 Implement #complete switch by default, replace with #partial switch #511 2019-12-22 12:03:48 +00:00
gingerBill 9db81498d8 Make the string type elements "immutable", akin to char const * in C
Allows for extra security and optimization benefits
2019-12-01 14:10:59 +00:00
gingerBill db2eff6847 Fix typo in json/parser.odin 2019-01-14 20:44:27 +00:00
gingerBill e047d9eb5e Update package json parser to store the end position on the values 2019-01-14 15:51:52 +00:00
gingerBill 5af20aa467 Make encoding/json use []byte rather than string 2019-01-07 23:08:38 +00:00
gingerBill 08598b9425 Support NaN and Infinity for JSON5 2019-01-06 22:25:02 +00:00
gingerBill d1b9f3ac74 package json; JSON5 support 2019-01-06 21:48:13 +00:00
gingerBill 9487f8c92e Add json.is_valid 2019-01-06 20:44:39 +00:00
gingerBill c5def60224 Begin work on package json 2019-01-06 20:37:12 +00:00