Skip to content

Commit 6a70e82

Browse files
committed
fix cases
1 parent 7c12577 commit 6a70e82

File tree

1 file changed

+61
-51
lines changed

1 file changed

+61
-51
lines changed

lib/json_mend/parser.rb

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ def parse_array
321321
if is_strictly_empty(value)
322322
@scanner.getch
323323
elsif value == "..." && @scanner.string.chars[@scanner.charpos - 1] == '.'
324+
# just skip
324325
else
325326
arr << value
326327
end
@@ -437,71 +438,72 @@ def parse_string
437438
skip_whitespaces
438439
if peek_char(1) == '\\'
439440
# Ok this is a quoted string, skip
440-
rstring_delimiter_missing = true
441-
i = skip_to_character(rstring_delimiter, start_idx: 1)
441+
rstring_delimiter_missing = false
442+
end
443+
444+
i = skip_to_character(rstring_delimiter, start_idx: 1)
445+
next_c = peek_char(i)
446+
if next_c
447+
i += 1
448+
# found a delimiter, now we need to check that is followed strictly by a comma or brace
449+
# or the string ended
450+
i = skip_whitespaces_at(start_idx: i)
442451
next_c = peek_char(i)
443-
if next_c
444-
i += 1
445-
# found a delimiter, now we need to check that is followed strictly by a comma or brace
446-
# or the string ended
447-
i = skip_whitespaces_at(start_idx: i)
452+
if next_c.nil? || [',', '}'].include?(next_c)
453+
rstring_delimiter_missing = false
454+
else
455+
# OK but this could still be some garbage at the end of the string
456+
# So we need to check if we find a new lstring_delimiter afterwards
457+
# If we do, maybe this is a missing delimiter
458+
i = skip_to_character(lstring_delimiter, start_idx: i)
448459
next_c = peek_char(i)
449-
if next_c.nil? || [',', '}'].include?(next_c)
460+
if next_c.nil?
450461
rstring_delimiter_missing = false
451462
else
452-
# OK but this could still be some garbage at the end of the string
453-
# So we need to check if we find a new lstring_delimiter afterwards
454-
# If we do, maybe this is a missing delimiter
455-
i = skip_to_character(lstring_delimiter, start_idx: i)
463+
# But again, this could just be something a bit stupid like "lorem, "ipsum" sic"
464+
# Check if we find a : afterwards (skipping space)
465+
i = skip_whitespaces_at(start_idx: i + 1)
456466
next_c = peek_char(i)
457-
if next_c.nil?
467+
if next_c && next_c != ":"
458468
rstring_delimiter_missing = false
459-
else
460-
# But again, this could just be something a bit stupid like "lorem, "ipsum" sic"
461-
# Check if we find a : afterwards (skipping space)
462-
i = skip_whitespaces_at(start_idx: i + 1)
463-
next_c = peek_char(i)
464-
if next_c && next_c != ":"
465-
rstring_delimiter_missing = false
466-
end
467469
end
468470
end
471+
end
472+
else
473+
# There could be a case in which even the next key:value is missing delimeters
474+
# because it might be a systemic issue with the output
475+
# So let's check if we can find a : in the string instead
476+
i = skip_to_character(':', start_idx: 1)
477+
next_c = peek_char(i)
478+
if next_c
479+
# OK then this is a systemic issue with the output
480+
break
469481
else
470-
# There could be a case in which even the next key:value is missing delimeters
471-
# because it might be a systemic issue with the output
472-
# So let's check if we can find a : in the string instead
473-
i = skip_to_character(':', start_idx: 1)
474-
next_c = peek_char(i)
475-
if next_c
476-
# OK then this is a systemic issue with the output
477-
break
478-
else
479-
# skip any whitespace first
480-
i = skip_whitespaces_at(start_idx: 1)
481-
# We couldn't find any rstring_delimeter before the end of the string
482-
# check if this is the last string of an object and therefore we can keep going
483-
# make an exception if this is the last char before the closing brace
484-
j = skip_to_character('}', start_idx: i)
485-
if j - i > 1
486-
# Ok it's not right after the comma
487-
# Let's ignore
488-
rstring_delimiter_missing = false
489-
elsif peek_char(j)
490-
# Check for an unmatched opening brace in string_acc
491-
string_acc.reverse.chars.each do |c|
492-
if c == '{'
493-
# Ok then this is part of the string
494-
rstring_delimiter_missing = false
495-
break
496-
end
482+
# skip any whitespace first
483+
i = skip_whitespaces_at(start_idx: 1)
484+
# We couldn't find any rstring_delimeter before the end of the string
485+
# check if this is the last string of an object and therefore we can keep going
486+
# make an exception if this is the last char before the closing brace
487+
j = skip_to_character('}', start_idx: i)
488+
if j - i > 1
489+
# Ok it's not right after the comma
490+
# Let's ignore
491+
rstring_delimiter_missing = false
492+
elsif peek_char(j)
493+
# Check for an unmatched opening brace in string_acc
494+
string_acc.reverse.chars.each do |c|
495+
if c == '{'
496+
# Ok then this is part of the string
497+
rstring_delimiter_missing = false
498+
break
497499
end
498500
end
499501
end
500502
end
503+
end
501504

502-
if rstring_delimiter_missing
503-
break
504-
end
505+
if rstring_delimiter_missing
506+
break
505507
end
506508
end
507509

@@ -511,6 +513,14 @@ def parse_string
511513
break unless peek_char(i)
512514
end
513515

516+
if current_context?(:object_value) && char == '}'
517+
# We found the end of an object while parsing a value
518+
# Check if the object is really over, to avoid doubling the closing brace
519+
i = skip_whitespaces_at(start_idx: 1)
520+
next_c = peek_char(i)
521+
break unless next_c
522+
end
523+
514524
string_acc << char
515525
@scanner.getch # Consume the character
516526
char = peek_char

0 commit comments

Comments
 (0)