Skip to content

Commit

Permalink
Makes sure JSON objects have a single root
Browse files Browse the repository at this point in the history
  • Loading branch information
Tpt committed Oct 13, 2022
1 parent b44762b commit 0664c3d
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
19 changes: 19 additions & 0 deletions lib/JsonEventParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export class JsonEventParser extends Transform {

private key: string | number | undefined = undefined;
private mode = 0;
private rootFound = false;
private readonly stack: { key: string | number | undefined; mode: number }[] = [];
private state: number = VALUE;
// Number of bytes remaining in multi byte utf8 char to read after split boundary
Expand Down Expand Up @@ -431,9 +432,20 @@ export class JsonEventParser extends Transform {
}

public _flush(callback: (error?: Error | null, data?: any) => void): void {
if (this.tState !== START) {
// We make sure we fully consume the buffer by reading an extra space
try {
this.parse(Buffer.from(' '));
} catch (error: unknown) {
return callback(<Error> error);
}
}
if (this.stack.length > 0) {
return callback(new Error('Unexpected end of file'));
}
if (!this.rootFound) {
return callback(new Error('A JSON file should not be empty'));
}
return callback();
}

Expand Down Expand Up @@ -463,6 +475,13 @@ export class JsonEventParser extends Transform {

private onToken(token: number, value: any): void {
if (this.state === VALUE || this.state === FIRST_VALUE) {
if (this.stack.length === 0) {
if (this.rootFound) {
this.parseError(token, value);
} else {
this.rootFound = true;
}
}
if (token === STRING || token === NUMBER || token === TRUE || token === FALSE || token === NULL) {
if (this.mode) {
this.state = COMMA;
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@
],
"coverageThreshold": {
"global": {
"branches": 95,
"branches": 94,
"functions": 100,
"lines": 96,
"statements": 96
"lines": 95,
"statements": 95
}
}
},
Expand Down
8 changes: 1 addition & 7 deletions test/parsing-test-suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ const IGNORED_FILE = new Set([
'n_number_neg_real_without_int_part.json',
'n_number_real_without_fractional_part.json',
'n_number_with_leading_zero.json',
'n_single_space.json',
'n_string_single_doublequote.json',
'n_structure_angle_bracket_..json',
'n_structure_double_array.json',
'n_structure_no_data.json',
'n_structure_object_with_trailing_garbage.json',
]);

describe('JsonEventParser', () => {
Expand All @@ -48,7 +42,7 @@ describe('JsonEventParser', () => {
const data = readFileSync(join(path, file));
if (file.startsWith('y_')) {
it(`should parse successfully ${file}`, async() => {
await parseJson(data);
await expect(parseJson(data)).resolves.toEqual(JSON.parse(data.toString()));
});
} else if (file.startsWith('n_')) {
it(`should fail on ${file}`, async() => {
Expand Down

0 comments on commit 0664c3d

Please sign in to comment.