Skip to content

Commit

Permalink
Fix unclosed object and array bug
Browse files Browse the repository at this point in the history
Before this fix, `parse()` would not throw on unclosed objects and
arrays. `parse()` will now throw on the following invalid JSON5
documents.

    {

    {a

    {a:

    {a:1

    {a:1,

    [

    [1

    [1,
  • Loading branch information
jordanbtucker committed Mar 18, 2018
1 parent 25929ab commit 0336c9c
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/parse.js
Expand Up @@ -839,6 +839,10 @@ const parseStates = {
// }

pop()
return

case 'eof':
throw invalidEOF()
}

// This code is unreachable since it's handled by the lexState.
Expand All @@ -851,14 +855,26 @@ const parseStates = {
// throw invalidToken()
// }

if (token.type === 'eof') {
throw invalidEOF()
}

parseState = 'beforePropertyValue'
},

beforePropertyValue () {
if (token.type === 'eof') {
throw invalidEOF()
}

push()
},

beforeArrayValue () {
if (token.type === 'eof') {
throw invalidEOF()
}

if (token.type === 'punctuator' && token.value === ']') {
pop()
return
Expand All @@ -873,6 +889,10 @@ const parseStates = {
// throw invalidToken()
// }

if (token.type === 'eof') {
throw invalidEOF()
}

switch (token.value) {
case ',':
parseState = 'beforePropertyName'
Expand All @@ -892,6 +912,10 @@ const parseStates = {
// throw invalidToken()
// }

if (token.type === 'eof') {
throw invalidEOF()
}

switch (token.value) {
case ',':
parseState = 'beforeArrayValue'
Expand Down
72 changes: 72 additions & 0 deletions test/errors.js
Expand Up @@ -365,6 +365,78 @@ describe('JSON5', () => {
err.columnNumber === 1
))
})

it('throws on unclosed objects before property names', () => {
assert.throws(() => {
JSON5.parse('{')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 2
))
})

it('throws on unclosed objects after property names', () => {
assert.throws(() => {
JSON5.parse('{a')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 3
))
})

it('throws on unclosed objects before property values', () => {
assert.throws(() => {
JSON5.parse('{a:')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 4
))
})

it('throws on unclosed objects after property values', () => {
assert.throws(() => {
JSON5.parse('{a:1')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 5
))
})

it('throws on unclosed arrays before values', () => {
assert.throws(() => {
JSON5.parse('[')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 2
))
})

it('throws on unclosed arrays after values', () => {
assert.throws(() => {
JSON5.parse('[1')
},
err => (
err instanceof SyntaxError &&
/^JSON5: invalid end of input/.test(err.message) &&
err.lineNumber === 1 &&
err.columnNumber === 3
))
})
})
})
})

0 comments on commit 0336c9c

Please sign in to comment.