Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CTS and fix #23

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# JSON P3 Change Log

## Version 1.3.4
## Version 1.3.4 (unreleased)

**Fixes**

- Fixed decoding of JSONPath escape sequences (those found in name selectors and string literals). Previously we were relying on `JSON.parse()` to unescape strings, now we have our own `unescapeString()` function that rejects invalid codepoints and surrogate pairs. See [jsonpath-compliance-test-suite #87](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite/pull/87).
- Fixed default minimum integer boundary for JSONPath indexes and slice steps. We were off by one.
- Fixed parsing of JSONPath integer literals with an exponent and an upper case 'e'. We now allow 'e' to be upper case.
- Fixed handling of trailing commas in JSONPath bracketed segments. We now raise a syntax error.
- Fixed handling of invalid JSONPath integer and float literals with extra minus signs, leading zeros or too many zeros. We now raise a syntax error in such cases.

## Version 1.3.3

Expand Down
2 changes: 1 addition & 1 deletion src/path/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class JSONPathEnvironment {
constructor(options: JSONPathEnvironmentOptions = {}) {
this.strict = options.strict ?? true;
this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) - 1;
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) + 1;
this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
this.nondeterministic = options.nondeterministic ?? false;
this.keysPattern = options.keysPattern ?? /~/y;
Expand Down
2 changes: 1 addition & 1 deletion src/path/lex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Token, TokenKind } from "./token";

// These regular expressions are to be used with Lexer.acceptMatchRun(),
// which expects the sticky flag to be set.
const exponentPattern = /e[+-]?\d+/y;
const exponentPattern = /[eE][+-]?\d+/y;
const functionNamePattern = /[a-z][a-z_0-9]*/y;
const indexPattern = /-?\d+/y;
const intPattern = /-?[0-9]+/y;
Expand Down
19 changes: 18 additions & 1 deletion src/path/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ export class Parser {
if (stream.peek.kind !== TokenKind.RBRACKET) {
stream.expectPeek(TokenKind.COMMA);
stream.next();
stream.expectPeekNot(TokenKind.RBRACKET, "unexpected trailing comma");
}

stream.next();
Expand Down Expand Up @@ -362,7 +363,23 @@ export class Parser {
}

protected parseNumber(stream: TokenStream): NumberLiteral {
return new NumberLiteral(stream.current, Number(stream.current.value));
const value = stream.current.value;
if (value.startsWith("0") && value.length > 1) {
throw new JSONPathSyntaxError(
`invalid number literal '${value}'`,
stream.current,
);
}

const num = Number(stream.current.value);

if (isNaN(num)) {
throw new JSONPathSyntaxError(
`invalid number literal '${value}'`,
stream.current,
);
}
return new NumberLiteral(stream.current, num);
}

protected parsePrefixExpression(stream: TokenStream): PrefixExpression {
Expand Down
7 changes: 7 additions & 0 deletions src/path/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,11 @@ export class TokenStream {
);
}
}

public expectPeekNot(kind: TokenKind, message: string): void {
const peeked = this.peek;
if (peeked.kind === kind) {
throw new JSONPathSyntaxError(message, peeked);
}
}
}
Loading