json-repair 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/CLAUDE.md +1 -1
- data/lib/json/repair/version.rb +1 -1
- data/lib/json/repairer.rb +23 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3e0898f751c91f7c3a026ccb107c319b983212296090031ba6b7a80713de18eb
|
|
4
|
+
data.tar.gz: 21028aa56a685b77ea42506333753deb1a903108b860843a877181b6af66b1a2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05752fda1b0ff27c2dcde8b217099460bdecb57efa4a3ab73ce534f27dfecf51673f68683f3009c8d159079bfb7fee3f0892f2c86e3f15d0e86a58d4c497c8f0
|
|
7
|
+
data.tar.gz: 46a8a689d2a969c3c7ca1395dbd4a5555e191e304c0cfffd3bbaec44d22066b2a8527efc7323267c62c21738364c2dddf917d20af3388ae87cf993d872d014a0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
### 2026-06-17 (0.14.0)
|
|
4
|
+
|
|
5
|
+
* Repair a leading `+` on numbers, like in JSON5: `+1.23` → `1.23`,
|
|
6
|
+
`[+1]` → `[1]`, `{"a": +5}` → `{"a":5}`, `+.5` → `0.5`. The `+` is
|
|
7
|
+
consumed and dropped (JSON has no explicit plus), so a leading-zero
|
|
8
|
+
number is quoted exactly like its unsigned form (`+05` → `"05"`),
|
|
9
|
+
while a `+` inside an exponent is left untouched (`2e+5` →
|
|
10
|
+
`200000.0`). The `+` must be followed by a digit or a leading dot, so
|
|
11
|
+
a bare `+` (and `+abc`, `++1`, `+e5`) still raises — and requiring a
|
|
12
|
+
digit/dot keeps the 0.12.0 empty-mantissa exponent guard intact.
|
|
13
|
+
Divergence from upstream
|
|
14
|
+
[jsonrepair](https://github.com/josdejong/jsonrepair) (v3.14.0 leaves
|
|
15
|
+
`+1.23` unrepaired, raising "Unexpected end of json string"),
|
|
16
|
+
commented at the site. Mirrors the leading-dot number repair (0.9.0).
|
|
17
|
+
|
|
3
18
|
### 2026-06-12 (0.13.0)
|
|
4
19
|
|
|
5
20
|
* Repair `#` hash line comments, like in Python, YAML, or Hjson:
|
data/CLAUDE.md
CHANGED
|
@@ -24,7 +24,7 @@ A few repair heuristics deliberately go **beyond** upstream (leading-dot numbers
|
|
|
24
24
|
|
|
25
25
|
### Entry point
|
|
26
26
|
|
|
27
|
-
`JSON.repair(str)` in `lib/json/repair.rb` first tries stdlib `JSON.parse` (fast path; opt out with `skip_json_loads: true`), and falls back to `JSON::Repairer.new(str).repair` when that raises. Either way the result is re-serialized with `JSON.generate`, so **output is canonical** — whitespace collapsed, numbers normalized, duplicate keys last-write-wins — and both paths agree on it.
|
|
27
|
+
`JSON.repair(str)` in `lib/json/repair.rb` first tries stdlib `JSON.parse` (fast path; opt out with `skip_json_loads: true`), and falls back to `JSON::Repairer.new(str).repair` when that raises. Either way the result is re-serialized with `JSON.generate`, so **output is canonical** — whitespace collapsed, numbers normalized, duplicate keys last-write-wins — and both paths agree on it. There is no pre-filter regex: the fast path simply runs `JSON.parse` and falls back to the Repairer on any `JSON::ParserError`. Comments are handled either way — the bundled `json` gem currently accepts `//` and `/*` comments (an implementation detail, not part of the `JSON.parse` contract) and `JSON.generate` drops them (`{} // c` → `{}`); were a future `json` release to reject them, they would simply raise and route to the Repairer, which strips comments too. Invalid escapes, NDJSON, Markdown fences, and trailing prose already make `JSON.parse` raise and so route to the Repairer. `return_objects: true` returns the parsed Ruby value instead of a string; `JSON.repair_file(path)` / `JSON.repair_io(io)` are convenience wrappers forwarding both options.
|
|
28
28
|
|
|
29
29
|
`JSON::JSONRepairError` is the only error raised for unrecoverable inputs; it exposes the failure `#position`. If the Repairer ever emits a string stdlib cannot parse (a Repairer bug), the `JSON::ParserError` is wrapped in `JSONRepairError` rather than leaked.
|
|
30
30
|
|
data/lib/json/repair/version.rb
CHANGED
data/lib/json/repairer.rb
CHANGED
|
@@ -741,6 +741,24 @@ module JSON
|
|
|
741
741
|
# Parse a number like 2.4 or 2.4e6
|
|
742
742
|
def parse_number
|
|
743
743
|
start = @index
|
|
744
|
+
|
|
745
|
+
# Divergence from upstream: accept and discard a leading "+". JSON5
|
|
746
|
+
# permits an explicit plus; JSON does not, so "+1.23" -> "1.23" and
|
|
747
|
+
# "{"a": +5}" -> {"a":5}. The "+" must be followed by a digit or a
|
|
748
|
+
# leading dot (mirroring the "-" branch below); otherwise this is not
|
|
749
|
+
# a number and we backtrack to the "+" so a bare "+" still raises.
|
|
750
|
+
# `start` stays on the "+", so the reset paths restore @index cleanly
|
|
751
|
+
# and the @index > start exponent guard below still implies a digit
|
|
752
|
+
# was consumed; the two emission sites drop the leading "+" before
|
|
753
|
+
# quoting. Upstream leaves "+1.23" unrepaired.
|
|
754
|
+
if @json[@index] == PLUS
|
|
755
|
+
@index += 1
|
|
756
|
+
unless digit?(@json[@index]) || @json[@index] == DOT
|
|
757
|
+
@index = start
|
|
758
|
+
return false
|
|
759
|
+
end
|
|
760
|
+
end
|
|
761
|
+
|
|
744
762
|
if @json[@index] == '-'
|
|
745
763
|
@index += 1
|
|
746
764
|
if at_end_of_number?
|
|
@@ -802,7 +820,9 @@ module JSON
|
|
|
802
820
|
|
|
803
821
|
if @index > start
|
|
804
822
|
# repair a number with leading zeros like "00789"
|
|
805
|
-
|
|
823
|
+
# drop a leading "+" first (see the PLUS branch above), so "+05"
|
|
824
|
+
# quotes like "05" and "+1.23" emits as "1.23"
|
|
825
|
+
num = @json[start...@index].delete_prefix(PLUS)
|
|
806
826
|
# the optional sign quotes "-05" like "05" (divergence from
|
|
807
827
|
# upstream, whose unsigned check lets "-05" through unrepaired)
|
|
808
828
|
has_invalid_leading_zero = num.match?(/^-?0\d/)
|
|
@@ -908,7 +928,8 @@ module JSON
|
|
|
908
928
|
# repair numbers cut off at the end
|
|
909
929
|
# this will only be called when we end after a '.', '-', or 'e' and does not
|
|
910
930
|
# change the number more than it needs to make it valid JSON
|
|
911
|
-
|
|
931
|
+
# delete_prefix drops a leading "+" (see the PLUS branch in parse_number)
|
|
932
|
+
num = "#{@json[start...@index]}0".delete_prefix(PLUS)
|
|
912
933
|
# quote a padded token that has an invalid leading zero, like "05e" ->
|
|
913
934
|
# "05e0", applying the same rule as the end of parse_number (divergence
|
|
914
935
|
# from upstream, which emits the invalid number raw)
|