Skip to content

Commit

Permalink
fix: handle repairing a missing comma at a newline
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong committed Dec 20, 2024
1 parent a7ae9f9 commit ecf9588
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 13 deletions.
11 changes: 11 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,17 @@ describe.each(implementations)('jsonrepair [$name]', ({ jsonrepair }) => {
test('should repair missing comma between object properties', () => {
expect(jsonrepair('{"a":2\n"b":3\n}')).toBe('{"a":2,\n"b":3\n}')
expect(jsonrepair('{"a":2\n"b":3\nc:4}')).toBe('{"a":2,\n"b":3,\n"c":4}')
expect(jsonrepair('{\n "firstName": "John"\n lastName: Smith')).toBe(
'{\n "firstName": "John",\n "lastName": "Smith"}'
)
expect(jsonrepair('{\n "firstName": "John" /* comment */ \n lastName: Smith')).toBe(
'{\n "firstName": "John", \n "lastName": "Smith"}'
)

// verify parsing a comma after a return (since in parseString we stop at a return)
expect(jsonrepair('{\n "firstName": "John"\n , lastName: Smith')).toBe(
'{\n "firstName": "John"\n , "lastName": "Smith"}'
)
})

test('should repair numbers at the end', () => {
Expand Down
20 changes: 13 additions & 7 deletions src/regular/jsonrepair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
isUnquotedStringDelimiter,
isValidStringCharacter,
isWhitespace,
isWhitespaceExceptNewline,
regexFunctionNameChar,
regexFunctionNameCharStart,
regexUrlChar,
Expand Down Expand Up @@ -135,25 +136,30 @@ export function jsonrepair(text: string): string {
return processed
}

function parseWhitespaceAndSkipComments(): boolean {
function parseWhitespaceAndSkipComments(skipNewline = true): boolean {
const start = i

let changed = parseWhitespace()
let changed = parseWhitespace(skipNewline)
do {
changed = parseComment()
if (changed) {
changed = parseWhitespace()
changed = parseWhitespace(skipNewline)
}
} while (changed)

return i > start
}

function parseWhitespace(): boolean {
function parseWhitespace(skipNewline: boolean): boolean {
const _isWhiteSpace = skipNewline ? isWhitespace : isWhitespaceExceptNewline
let whitespace = ''
let normal: boolean
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
while ((normal = isWhitespace(text.charCodeAt(i))) || isSpecialWhitespace(text.charCodeAt(i))) {

while (
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
(normal = _isWhiteSpace(text.charCodeAt(i))) ||
isSpecialWhitespace(text.charCodeAt(i))
) {
if (normal) {
whitespace += text[i]
} else {
Expand Down Expand Up @@ -486,7 +492,7 @@ export function jsonrepair(text: string): string {
i++
output += str

parseWhitespaceAndSkipComments()
parseWhitespaceAndSkipComments(false)

if (
stopAtDelimiter ||
Expand Down
15 changes: 9 additions & 6 deletions src/streaming/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
isUnquotedStringDelimiter,
isValidStringCharacter,
isWhitespace,
isWhitespaceExceptNewline,
regexFunctionNameChar,
regexFunctionNameCharStart,
regexUrlChar,
Expand Down Expand Up @@ -494,26 +495,28 @@ export function jsonrepairCore({
return false
}

function parseWhitespaceAndSkipComments(): boolean {
function parseWhitespaceAndSkipComments(skipNewline = true): boolean {
const start = i

let changed = parseWhitespace()
let changed = parseWhitespace(skipNewline)
do {
changed = parseComment()
if (changed) {
changed = parseWhitespace()
changed = parseWhitespace(skipNewline)
}
} while (changed)

return i > start
}

function parseWhitespace(): boolean {
function parseWhitespace(skipNewline: boolean): boolean {
const _isWhiteSpace = skipNewline ? isWhitespace : isWhitespaceExceptNewline
let whitespace = ''
let normal: boolean

while (
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
(normal = isWhitespace(input.charCodeAt(i))) ||
(normal = _isWhiteSpace(input.charCodeAt(i))) ||
isSpecialWhitespace(input.charCodeAt(i))
) {
if (normal) {
Expand Down Expand Up @@ -679,7 +682,7 @@ export function jsonrepairCore({
output.push('"')
i++

parseWhitespaceAndSkipComments()
parseWhitespaceAndSkipComments(false)

if (
stopAtDelimiter ||
Expand Down
8 changes: 8 additions & 0 deletions src/utils/stringUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ export function isWhitespace(code: number): boolean {
return code === codeSpace || code === codeNewline || code === codeTab || code === codeReturn
}

/**
* Check if the given character is a whitespace character like space or tab,
* but NOT a newline
*/
export function isWhitespaceExceptNewline(code: number): boolean {
return code === codeSpace || code === codeTab || code === codeReturn
}

/**
* Check if the given character is a special whitespace character, some
* unicode variant
Expand Down

0 comments on commit ecf9588

Please sign in to comment.