224 Commits
Author SHA1 Message Date
bplu4t2f 1489279f20 encoding/json: Simplify format_float with Float_Flags. 2026-10-27 17:48:27 +01:00
bplu4t2f 9b399220f5 Merge branch 'master' into simplify-strings-io-fmt-strconv-interactions 2026-10-27 15:49:41 +01:00
gingerBill aa342487d0 core:encoding/json: Check object keys as strictly as string values as strictly as string values 2026-10-27 11:54:18 +00:00
gingerBill 92a99b0f18 core:encoding/json: Skip and copy validated string values without rescanning 2026-10-27 11:28:28 +00:00
gingerBill fee4c80d4c core:encoding/json: Fix array count for keys that end at a newline 2026-10-27 11:28:18 +00:00
gingerBill a2a97fd384 core:encoding/json: Dispatch common tokens on one byte switch in get_token 2026-10-27 10:33:07 +00:00
gingerBill 47a10c3529 core:encoding/json: Use parse_integer for Values; out-of-range ones wrap 2026-10-27 09:51:07 +00:00
gingerBill 589e597d7a core:encoding/json: Scan digit runs eight bytes at a time 2026-10-27 09:24:53 +00:00
gingerBill 89884834ac core:encoding/json: Count elements of validated arrays without the tokenizer 2026-10-27 08:54:11 +00:00
gingerBill 54f4dff6e3 core:encoding/json: Check each string once by reusing the tokenizer's verdict 2026-10-26 23:01:06 +00:00
gingerBill 22ea4c548d core:encoding/json: Marshal floats as the shortest text that round-trips 2026-10-26 22:47:20 +00:00
gingerBill 5f349bae69 core:encoding/json: Match an empty key only to a field tagged json:"" 2026-10-26 22:25:05 +00:00
gingerBill 918b39d836 core:encoding/json: Error on duplicate struct fields; resolve names lazily 2026-10-26 22:11:18 +00:00
gingerBill a157887c3e core:encoding/json: Drop temporary key/scalar allocations; add .Reserve_Maps 2026-10-26 21:21:46 +00:00
gingerBill cb934fd53f core:encoding/json: Add Unmarshal_Flags with .Skip_Validation 2026-10-26 20:49:13 +00:00
gingerBill 5d6edc58e4 core:encoding/json: Drop bounds-check blocks that showed no measurable gain 2026-10-26 20:24:18 +00:00
gingerBill 439099e922 core:encoding/json: Scan plain string runs 8 bytes at a time and validate inline 2026-10-26 20:16:25 +00:00
gingerBill 2649e5d627 core:encoding/json: Scan tokens bytewise and skip values without building them 2026-10-26 20:01:11 +00:00
gingerBill 0570fafe1c core:encoding/json: Parse short decimal integers directly in unmarshal 2026-10-26 19:40:29 +00:00
bplu4t2f 51f72ec0da encoding/json: Implement marshaling JSON string values directly in this package, rather than hammering it into io. Rationale: Writing a JSON string value is an entirely different operation compared to write_quoted_string, and is specific to encoding/json. 2026-10-16 14:20:08 +02:00
bplu4t2f 4fa98fae77 encoding/json: Protect public marshaling APIs against misuse - Marshal_Options is also the mutable state object; was passed around by pointer, but never nil checked. 2026-10-15 16:55:37 +02:00
corleypc 3a840a0bd3 fix use after scope in core:encoding/json 2026-10-13 17:25:07 +03:00
Ben Botwin 2796bf0fd0 removes private from unmarshal_value for use in user unmarshalers 2026-09-29 16:58:31 -04:00
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
kalsprite deeddc7b33 add missing endian 128 types 2026-08-25 23:03:11 -07:00
gingerBill 7d32c733d3 json.match utility procedure 2026-06-29 13:44:45 +01:00
gingerBill 9e713e2940 Update core:encoding/json to use proc groups and @(require_results) 2026-06-29 13:44:29 +01:00
Bärtschi Robin 3883d079c8 Fix #6874 2026-06-24 08:04:17 +02:00
gingerBill 8c63a70aad Fix identation 2026-06-23 13:14:56 +01:00
gingerBill 2b684ed1ec Add json.unparse allowing for json.Value to io.Writer without the need for RTTI 2026-06-23 12:47:38 +01:00
A1029384756 45a79f96f0 [encoding/json] add support for unmarshalling fixed capacity dynamic arrays 2026-05-21 11:48:25 -04:00
Brad Lewis 87d58b9fb7 Handle invalid utf8 when parsing json 2026-05-10 16:23:26 +10:00
Laytan d90cc4e3b6 json: fix user unmarshaller example (#6468)
* json: fix user unmarshaller example

- Returning `.None` in the custom unmarshaler is wrong, should be `nil`
- `advance_token` has to be called

Besides the fixes I made it an actual example that will show up on the package docs
2026-03-23 21:28:47 +01:00
gingerBill 4df2de057b Add Type_Info_Fixed_Capacity_Dynamic_Array to json 2026-03-11 18:43:01 +00:00
Jeroen van Rijn b6ea6f7a12 Merge pull request #5882 from IllusionMan1212/custom-json-marshalling
encoding/json: custom json (un)marshalling
2026-01-01 16:07:01 +00:00
dozn 8fea2b783c [encoding/json] Allow Unmarshalling to rune
Fixes https://github.com/odin-lang/Odin/issues/6061
2025-12-30 18:10:07 -08:00
dozn 589dbbddd2 [encoding/json] Fix Escapes When Marshalling
Fixes https://github.com/odin-lang/Odin/issues/6060 and https://github.com/odin-lang/Odin/issues/6075
The boolean "true" was setting `html_safe` instead of `for_json`.
Chalk one up for the "use enums instead of booleans" crowd.
2025-12-30 17:02:06 -08:00
dozn affaefc13a Moved first_iteration up a couple lines so it makes sense readability-wise. 2025-12-30 04:42:06 -08:00
dozn ba68d75c6f Add JSON5/SJSON Comments When Marshalling
Allows user-facing JSON5/SJSON to have comments explaining field usage.
`json.Marshal_Options.pretty` must be enabled since we only use single-line comments (not to mention it wouldn't be terribly useful without `pretty` set anyways).
We don't escape anything, so `\n` will display as "\n", but you're still able to enter in a proper newline character and it'll be displayed on multiple lines.
2025-12-29 12:23:54 -08:00
Sylphrena 6441fc09e0 Fix standard json parsing / unmarshalling issue for pure arrays 2025-12-29 15:35:34 +01:00
Jeroen van Rijn 83fb7ba952 Make custom JSON (un)marshalers more like core:fmt's 2025-12-10 17:54:12 +01:00
Hisham Aburaqibah 72d65603eb encoding/json: error handling for custom (un)marshallers 2025-12-02 22:46:35 +02:00
IllusionMan1212 4b9e15786d encoding/json: custom json (un)marshalling 2025-12-02 22:46:31 +02:00
Neirokan 8cdf7ade48 encoding/json: clone unquoted strings 2025-11-06 19:24:58 +03:00
Jeroen van Rijn 236111864e Link doc lines to source specifications. 2025-10-10 18:29:52 +02:00
Jeroen van Rijn ece213afca Render examples. 2025-10-10 12:24:28 +02:00
Jeroen van Rijn 7a9ea3ee6d Further overhaul of package line comments. 2025-10-09 23:05:29 +02:00
Jeroen van Rijn 288b45f50c package lines for encoding 2025-10-09 16:34:18 +02:00
Courtney Strachan 69ad94d8a8 Followup fix to #4895 2025-10-05 19:22:04 -07:00