json-repair 0.11.1 → 0.11.2
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/.rubocop.yml +10 -0
- data/CHANGELOG.md +21 -1
- data/lib/json/repair/version.rb +1 -1
- data/lib/json/repairer.rb +25 -5
- data/sig/json/repairer.rbs +2 -0
- 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: 2d7b2f30c2451f62471beabed342ff8360f644e4ae703fa3e0f5490e44d4f0d1
|
|
4
|
+
data.tar.gz: 254abaa4ab104a0cc6650d02f099ebb00b0600ef213b00866da266159b6c1a37
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfd417574888a7ff44a03870f48ab6e02c7bb7ae80189262e093425ba52e3943982f6ab36170c1cac6a3871e3d3379469b8319bbaa6defe8a0d473a7be6fe2a9
|
|
7
|
+
data.tar.gz: 208611ef2a09d4e3a5c91afe98334dfc7443a3db56de9624cfa82a3dea1e0c0480de18227646a96dac3c46f64af526e229f70dd9de4cd41cc1160a703b132a0b
|
data/.rubocop.yml
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
# Merge our Exclude lists with RuboCop's defaults (vendor/**/*, tmp/**/*, …)
|
|
2
|
+
# instead of replacing them — CI vendors gems into vendor/bundle, which
|
|
3
|
+
# RuboCop must keep skipping.
|
|
4
|
+
inherit_mode:
|
|
5
|
+
merge:
|
|
6
|
+
- Exclude
|
|
7
|
+
|
|
1
8
|
AllCops:
|
|
2
9
|
TargetRubyVersion: 3.0
|
|
10
|
+
Exclude:
|
|
11
|
+
# gitignored local planning notes and scratch tooling (see CLAUDE.md)
|
|
12
|
+
- docs/**/*
|
|
3
13
|
|
|
4
14
|
Style/Documentation:
|
|
5
15
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
-
### 2026-06-12 (0.11.
|
|
3
|
+
### 2026-06-12 (0.11.2)
|
|
4
|
+
|
|
5
|
+
* Fix the 0.11.0 doubled-colon repair silently mangling objects with a
|
|
6
|
+
stray junk word between pairs. `{"value_1": true, COMMENT "value_2":
|
|
7
|
+
"data"}` returned `{"value_1":true,"COMMENT":"value_2\": \"data"}`
|
|
8
|
+
(the junk word became a key and swallowed the real pair), and
|
|
9
|
+
`{ "key": "value" COMMENT "key2": "value2" }` returned a single
|
|
10
|
+
glued string value. Both shapes now raise "Object key expected"
|
|
11
|
+
again at the same positions as upstream
|
|
12
|
+
[jsonrepair](https://github.com/josdejong/jsonrepair) v3.14.0,
|
|
13
|
+
restoring the pre-0.11.0 behavior: the merge is skipped when the
|
|
14
|
+
pair already needed a missing-colon repair or the value string was
|
|
15
|
+
itself salvaged by the unescaped-quote repair — signals that the
|
|
16
|
+
pair was malformed in a way the merge would compound, not fix. The
|
|
17
|
+
salvage signal survives string concatenation: in
|
|
18
|
+
`{"a": "b" x "c" + "d": "e"}` the `+ "d"` segment no longer clears
|
|
19
|
+
it (caught in review by Copilot). All
|
|
20
|
+
0.11.0 repairs (canonical, greedy, escaped quotes, unquoted
|
|
21
|
+
keys/values) are unchanged. Go and Python `json_repair` instead
|
|
22
|
+
drop the junk word; we deliberately keep raising rather than
|
|
23
|
+
silently discarding input (see the 0.11.0 note).
|
|
4
24
|
|
|
5
25
|
* Fix a `TypeError` crash on input ending in a lone backslash inside a
|
|
6
26
|
string: `"abc\` now repairs to `"abc"` (likewise `"\` → `""`,
|
data/lib/json/repair/version.rb
CHANGED
data/lib/json/repairer.rb
CHANGED
|
@@ -32,6 +32,7 @@ module JSON
|
|
|
32
32
|
@json = json
|
|
33
33
|
@index = 0
|
|
34
34
|
@output = +''
|
|
35
|
+
@repaired_unescaped_quote = false
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def repair
|
|
@@ -295,8 +296,14 @@ module JSON
|
|
|
295
296
|
end
|
|
296
297
|
|
|
297
298
|
# repair: an object string value with unescaped quotes around a
|
|
298
|
-
# colon, like {"a": "b": "c"}
|
|
299
|
-
|
|
299
|
+
# colon, like {"a": "b": "c"}. Skipped when this pair already
|
|
300
|
+
# needed a repair that makes the merge compound garbage: a
|
|
301
|
+
# missing colon (the "key" was a stray junk word, like
|
|
302
|
+
# {"v1": true, COMMENT "v2": "data"}) or a value glued together
|
|
303
|
+
# by the unescaped-quote repair (like
|
|
304
|
+
# {"k": "v" COMMENT "k2": "v2"}); both keep raising, matching
|
|
305
|
+
# upstream
|
|
306
|
+
repair_doubled_colon if processed_value && processed_colon && !@repaired_unescaped_quote
|
|
300
307
|
end
|
|
301
308
|
|
|
302
309
|
if @json[@index] == CLOSING_BRACE
|
|
@@ -315,9 +322,13 @@ module JSON
|
|
|
315
322
|
# (the unescaped-quotes reading of the input). Greedy: keeps merging
|
|
316
323
|
# while another `: "..."` follows. Only the string-colon-string
|
|
317
324
|
# shape is repaired; anything else falls through to the regular
|
|
318
|
-
# error paths.
|
|
319
|
-
#
|
|
320
|
-
#
|
|
325
|
+
# error paths. The call site additionally requires the pair's colon
|
|
326
|
+
# to be present in the input and the value string to have parsed
|
|
327
|
+
# without the unescaped-quote repair (@repaired_unescaped_quote) —
|
|
328
|
+
# when either repair already fired, the pair was malformed in a way
|
|
329
|
+
# this merge would compound, not fix. Divergence from upstream
|
|
330
|
+
# (which raises "Object key expected" as of v3.14.0), matching the
|
|
331
|
+
# Go and Python json-repair libraries on the canonical case.
|
|
321
332
|
def repair_doubled_colon
|
|
322
333
|
loop do
|
|
323
334
|
colon = @index
|
|
@@ -399,6 +410,9 @@ module JSON
|
|
|
399
410
|
# and fixing the string by inserting a quote there, or stopping at a
|
|
400
411
|
# stop index detected in the first iteration.
|
|
401
412
|
def parse_string(stop_at_delimiter: false, stop_at_index: -1)
|
|
413
|
+
# fresh parse (the backtracking re-invocations below rebuild the
|
|
414
|
+
# string from scratch, so they reset too); see repair_doubled_colon
|
|
415
|
+
@repaired_unescaped_quote = false
|
|
402
416
|
skip_escape_chars = @json[@index] == BACKSLASH
|
|
403
417
|
if skip_escape_chars
|
|
404
418
|
# repair: remove the first escape character
|
|
@@ -508,6 +522,7 @@ module JSON
|
|
|
508
522
|
|
|
509
523
|
# repair unescaped quote
|
|
510
524
|
str = "#{str[...o_quote]}\\#{str[o_quote..]}"
|
|
525
|
+
@repaired_unescaped_quote = true
|
|
511
526
|
elsif stop_at_delimiter && unquoted_string_delimiter?(@json[@index])
|
|
512
527
|
# we're in the mode to stop the string at the first delimiter
|
|
513
528
|
# because there is an end quote missing
|
|
@@ -807,7 +822,12 @@ module JSON
|
|
|
807
822
|
# repair: remove the end quote of the first string
|
|
808
823
|
@output = strip_last_occurrence(@output, '"', strip_remaining_text: true)
|
|
809
824
|
start = @output.length
|
|
825
|
+
# the segments form one logical string value: keep the doubled-colon
|
|
826
|
+
# guard's flag set when an earlier segment needed the unescaped-quote
|
|
827
|
+
# repair (parse_string resets it on entry)
|
|
828
|
+
repaired_earlier_segment = @repaired_unescaped_quote
|
|
810
829
|
parsed_str = parse_string
|
|
830
|
+
@repaired_unescaped_quote ||= repaired_earlier_segment
|
|
811
831
|
@output = if parsed_str
|
|
812
832
|
# repair: remove the start quote of the second string
|
|
813
833
|
remove_at_index(@output, start, 1)
|
data/sig/json/repairer.rbs
CHANGED