json-p3 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/json-p3.cjs.js +175 -10
- package/dist/json-p3.esm.js +175 -10
- package/dist/json-p3.iife.js +175 -10
- package/dist/json-p3.iife.min.js +1 -1
- package/dist/json-p3.iife.min.js.map +1 -1
- package/dist/path/parse.d.ts +26 -1
- package/dist/path/token.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/json-p3.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* json-p3 version 1.3.
|
|
2
|
+
* json-p3 version 1.3.4
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -2552,6 +2552,12 @@ class TokenStream {
|
|
|
2552
2552
|
throw new JSONPathSyntaxError(`expected token '${kind}', found '${peeked.kind}'`, peeked);
|
|
2553
2553
|
}
|
|
2554
2554
|
}
|
|
2555
|
+
expectPeekNot(kind, message) {
|
|
2556
|
+
const peeked = this.peek;
|
|
2557
|
+
if (peeked.kind === kind) {
|
|
2558
|
+
throw new JSONPathSyntaxError(message, peeked);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2555
2561
|
}
|
|
2556
2562
|
|
|
2557
2563
|
/** A lexer that accepts additional, non-standard tokens. */
|
|
@@ -2559,7 +2565,7 @@ class TokenStream {
|
|
|
2559
2565
|
|
|
2560
2566
|
// These regular expressions are to be used with Lexer.acceptMatchRun(),
|
|
2561
2567
|
// which expects the sticky flag to be set.
|
|
2562
|
-
const exponentPattern = /
|
|
2568
|
+
const exponentPattern = /[eE][+-]?\d+/y;
|
|
2563
2569
|
const functionNamePattern = /[a-z][a-z_0-9]*/y;
|
|
2564
2570
|
const indexPattern = /-?\d+/y;
|
|
2565
2571
|
const intPattern = /-?[0-9]+/y;
|
|
@@ -4002,7 +4008,7 @@ class Parser {
|
|
|
4002
4008
|
switch (stream.current.kind) {
|
|
4003
4009
|
case TokenKind.SINGLE_QUOTE_STRING:
|
|
4004
4010
|
case TokenKind.DOUBLE_QUOTE_STRING:
|
|
4005
|
-
items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current
|
|
4011
|
+
items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current), false));
|
|
4006
4012
|
break;
|
|
4007
4013
|
case TokenKind.FILTER:
|
|
4008
4014
|
items.push(this.parseFilter(stream));
|
|
@@ -4022,7 +4028,7 @@ class Parser {
|
|
|
4022
4028
|
break;
|
|
4023
4029
|
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
4024
4030
|
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
4025
|
-
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current
|
|
4031
|
+
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current), false));
|
|
4026
4032
|
break;
|
|
4027
4033
|
case TokenKind.KEYS_FILTER:
|
|
4028
4034
|
items.push(this.parseFilter(stream, true));
|
|
@@ -4038,6 +4044,7 @@ class Parser {
|
|
|
4038
4044
|
if (stream.peek.kind !== TokenKind.RBRACKET) {
|
|
4039
4045
|
stream.expectPeek(TokenKind.COMMA);
|
|
4040
4046
|
stream.next();
|
|
4047
|
+
stream.expectPeekNot(TokenKind.RBRACKET, "unexpected trailing comma");
|
|
4041
4048
|
}
|
|
4042
4049
|
stream.next();
|
|
4043
4050
|
}
|
|
@@ -4070,7 +4077,15 @@ class Parser {
|
|
|
4070
4077
|
return new StringLiteral(stream.current, this.decodeString(stream.current));
|
|
4071
4078
|
}
|
|
4072
4079
|
parseNumber(stream) {
|
|
4073
|
-
|
|
4080
|
+
const value = stream.current.value;
|
|
4081
|
+
if (value.startsWith("0") && value.length > 1) {
|
|
4082
|
+
throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
|
|
4083
|
+
}
|
|
4084
|
+
const num = Number(stream.current.value);
|
|
4085
|
+
if (isNaN(num)) {
|
|
4086
|
+
throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
|
|
4087
|
+
}
|
|
4088
|
+
return new NumberLiteral(stream.current, num);
|
|
4074
4089
|
}
|
|
4075
4090
|
parsePrefixExpression(stream) {
|
|
4076
4091
|
stream.expect(TokenKind.NOT);
|
|
@@ -4181,11 +4196,155 @@ class Parser {
|
|
|
4181
4196
|
return left;
|
|
4182
4197
|
}
|
|
4183
4198
|
decodeString(token) {
|
|
4184
|
-
|
|
4199
|
+
return this.unescapeString(token.kind === TokenKind.SINGLE_QUOTE_STRING ? token.value.replaceAll('"', '\\"').replaceAll("\\'", "'") : token.value, token);
|
|
4200
|
+
}
|
|
4201
|
+
unescapeString(value, token) {
|
|
4202
|
+
const rv = [];
|
|
4203
|
+
const length = value.length;
|
|
4204
|
+
let index = 0;
|
|
4205
|
+
let codepoint;
|
|
4206
|
+
while (index < length) {
|
|
4207
|
+
const ch = value[index];
|
|
4208
|
+
if (ch === "\\") {
|
|
4209
|
+
// Handle escape sequences
|
|
4210
|
+
index += 1; // Move past '\'
|
|
4211
|
+
|
|
4212
|
+
switch (value[index]) {
|
|
4213
|
+
case '"':
|
|
4214
|
+
rv.push('"');
|
|
4215
|
+
break;
|
|
4216
|
+
case "\\":
|
|
4217
|
+
rv.push("\\");
|
|
4218
|
+
break;
|
|
4219
|
+
case "/":
|
|
4220
|
+
rv.push("/");
|
|
4221
|
+
break;
|
|
4222
|
+
case "b":
|
|
4223
|
+
rv.push("\x08");
|
|
4224
|
+
break;
|
|
4225
|
+
case "f":
|
|
4226
|
+
rv.push("\x0C");
|
|
4227
|
+
break;
|
|
4228
|
+
case "n":
|
|
4229
|
+
rv.push("\n");
|
|
4230
|
+
break;
|
|
4231
|
+
case "r":
|
|
4232
|
+
rv.push("\r");
|
|
4233
|
+
break;
|
|
4234
|
+
case "t":
|
|
4235
|
+
rv.push("\t");
|
|
4236
|
+
break;
|
|
4237
|
+
case "u":
|
|
4238
|
+
[codepoint, index] = this.decodeHexChar(value, index, token);
|
|
4239
|
+
rv.push(this.stringFromCodePoint(codepoint, token));
|
|
4240
|
+
break;
|
|
4241
|
+
default:
|
|
4242
|
+
// TODO: This is unreachable. The lexer will catch unknown escape sequences.
|
|
4243
|
+
throw new JSONPathSyntaxError(`unknown escape sequence at index ${token.index + index - 1}`, token);
|
|
4244
|
+
}
|
|
4245
|
+
} else {
|
|
4246
|
+
this.stringFromCodePoint(ch.codePointAt(0), token);
|
|
4247
|
+
rv.push(ch);
|
|
4248
|
+
}
|
|
4249
|
+
index += 1;
|
|
4250
|
+
}
|
|
4251
|
+
return rv.join("");
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
/**
|
|
4255
|
+
* Decode a `\uXXXX` or `\uXXXX\uXXXX` escape sequence from _value_ at _index_.
|
|
4256
|
+
*
|
|
4257
|
+
* @param value - A string value containing the sequence to decode.
|
|
4258
|
+
* @param index - The start index of an escape sequence in _value_.
|
|
4259
|
+
* @param token - The token for the string value.
|
|
4260
|
+
* @returns - A codepoint, new index tuple.
|
|
4261
|
+
*/
|
|
4262
|
+
decodeHexChar(value, index, token) {
|
|
4263
|
+
const length = value.length;
|
|
4264
|
+
if (index + 4 >= length) {
|
|
4265
|
+
throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 1}`, token);
|
|
4266
|
+
}
|
|
4267
|
+
index += 1; // Move past 'u'
|
|
4268
|
+
let codepoint = this.parseHexDigits(value.slice(index, index + 4), token);
|
|
4269
|
+
if (isLowSurrogate(codepoint)) {
|
|
4270
|
+
throw new JSONPathSyntaxError(`unexpected low surrogate codepoint at index ${token.index + index - 2}`, token);
|
|
4271
|
+
}
|
|
4272
|
+
if (isHighSurrogate(codepoint)) {
|
|
4273
|
+
// Expect a surrogate pair.
|
|
4274
|
+
if (!(index + 9 < length && value[index + 4] === "\\" && value[index + 5] === "u")) {
|
|
4275
|
+
throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 2}`, token);
|
|
4276
|
+
}
|
|
4277
|
+
const lowSurrogate = this.parseHexDigits(value.slice(index + 6, index + 10), token);
|
|
4278
|
+
if (!isLowSurrogate(lowSurrogate)) {
|
|
4279
|
+
throw new JSONPathSyntaxError(`unexpected codepoint at index ${token.index + index + 4}`, token);
|
|
4280
|
+
}
|
|
4281
|
+
codepoint = 0x10000 + ((codepoint & 0x03ff) << 10 | lowSurrogate & 0x03ff);
|
|
4282
|
+
return [codepoint, index + 9];
|
|
4283
|
+
}
|
|
4284
|
+
return [codepoint, index + 3];
|
|
4285
|
+
}
|
|
4286
|
+
|
|
4287
|
+
/**
|
|
4288
|
+
* Parse a hexadecimal string as an integer.
|
|
4289
|
+
*
|
|
4290
|
+
* @param digits - Hexadecimal digit string.
|
|
4291
|
+
* @param token - The token for the string value.
|
|
4292
|
+
* @returns - The number representation of _digits_.
|
|
4293
|
+
*
|
|
4294
|
+
* Note that we're not using `parseInt(digits, 16)` because it accepts `+`
|
|
4295
|
+
* and `-` and things we don't allow.
|
|
4296
|
+
*/
|
|
4297
|
+
parseHexDigits(digits, token) {
|
|
4298
|
+
const encoder = new TextEncoder();
|
|
4299
|
+
let codepoint = 0;
|
|
4300
|
+
for (const digit of encoder.encode(digits)) {
|
|
4301
|
+
codepoint <<= 4;
|
|
4302
|
+
switch (digit) {
|
|
4303
|
+
case 48:
|
|
4304
|
+
case 49:
|
|
4305
|
+
case 50:
|
|
4306
|
+
case 51:
|
|
4307
|
+
case 52:
|
|
4308
|
+
case 53:
|
|
4309
|
+
case 54:
|
|
4310
|
+
case 55:
|
|
4311
|
+
case 56:
|
|
4312
|
+
case 57:
|
|
4313
|
+
codepoint |= digit - 48; // '0'
|
|
4314
|
+
break;
|
|
4315
|
+
case 97:
|
|
4316
|
+
case 98:
|
|
4317
|
+
case 99:
|
|
4318
|
+
case 100:
|
|
4319
|
+
case 101:
|
|
4320
|
+
case 102:
|
|
4321
|
+
codepoint |= digit - 97 + 10; // 'a'
|
|
4322
|
+
break;
|
|
4323
|
+
case 65:
|
|
4324
|
+
case 66:
|
|
4325
|
+
case 67:
|
|
4326
|
+
case 68:
|
|
4327
|
+
case 69:
|
|
4328
|
+
case 70:
|
|
4329
|
+
codepoint |= digit - 65 + 10; // 'A'
|
|
4330
|
+
break;
|
|
4331
|
+
default:
|
|
4332
|
+
throw new JSONPathSyntaxError("invalid \\uXXXX escape sequence", token);
|
|
4333
|
+
}
|
|
4334
|
+
}
|
|
4335
|
+
return codepoint;
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
/** Check the codepoint is valid and return its string representation. */
|
|
4339
|
+
stringFromCodePoint(codepoint, token) {
|
|
4340
|
+
if (codepoint === undefined || codepoint <= 0x1f) {
|
|
4341
|
+
throw new JSONPathSyntaxError(`invalid character`, token);
|
|
4342
|
+
}
|
|
4185
4343
|
try {
|
|
4186
|
-
return
|
|
4344
|
+
return String.fromCodePoint(codepoint);
|
|
4187
4345
|
} catch {
|
|
4188
|
-
|
|
4346
|
+
// This should not be reachable.
|
|
4347
|
+
throw new JSONPathSyntaxError("invalid escape sequence", token);
|
|
4189
4348
|
}
|
|
4190
4349
|
}
|
|
4191
4350
|
throwForNonComparable(expr) {
|
|
@@ -4205,6 +4364,12 @@ class Parser {
|
|
|
4205
4364
|
}
|
|
4206
4365
|
}
|
|
4207
4366
|
}
|
|
4367
|
+
function isHighSurrogate(codepoint) {
|
|
4368
|
+
return codepoint >= 0xd800 && codepoint <= 0xdbff;
|
|
4369
|
+
}
|
|
4370
|
+
function isLowSurrogate(codepoint) {
|
|
4371
|
+
return codepoint >= 0xdc00 && codepoint <= 0xdfff;
|
|
4372
|
+
}
|
|
4208
4373
|
|
|
4209
4374
|
/**
|
|
4210
4375
|
* JSONPath environment options. The defaults are in compliance with JSONPath
|
|
@@ -4262,7 +4427,7 @@ class JSONPathEnvironment {
|
|
|
4262
4427
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
4263
4428
|
this.strict = options.strict ?? true;
|
|
4264
4429
|
this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
|
|
4265
|
-
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53)
|
|
4430
|
+
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) + 1;
|
|
4266
4431
|
this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
|
|
4267
4432
|
this.nondeterministic = options.nondeterministic ?? false;
|
|
4268
4433
|
this.keysPattern = options.keysPattern ?? /~/y;
|
|
@@ -4986,7 +5151,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4986
5151
|
apply: apply
|
|
4987
5152
|
});
|
|
4988
5153
|
|
|
4989
|
-
const version = "1.3.
|
|
5154
|
+
const version = "1.3.4";
|
|
4990
5155
|
|
|
4991
5156
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
4992
5157
|
exports.FunctionExpressionType = FunctionExpressionType;
|
package/dist/json-p3.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* json-p3 version 1.3.
|
|
2
|
+
* json-p3 version 1.3.4
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -2550,6 +2550,12 @@ class TokenStream {
|
|
|
2550
2550
|
throw new JSONPathSyntaxError(`expected token '${kind}', found '${peeked.kind}'`, peeked);
|
|
2551
2551
|
}
|
|
2552
2552
|
}
|
|
2553
|
+
expectPeekNot(kind, message) {
|
|
2554
|
+
const peeked = this.peek;
|
|
2555
|
+
if (peeked.kind === kind) {
|
|
2556
|
+
throw new JSONPathSyntaxError(message, peeked);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2553
2559
|
}
|
|
2554
2560
|
|
|
2555
2561
|
/** A lexer that accepts additional, non-standard tokens. */
|
|
@@ -2557,7 +2563,7 @@ class TokenStream {
|
|
|
2557
2563
|
|
|
2558
2564
|
// These regular expressions are to be used with Lexer.acceptMatchRun(),
|
|
2559
2565
|
// which expects the sticky flag to be set.
|
|
2560
|
-
const exponentPattern = /
|
|
2566
|
+
const exponentPattern = /[eE][+-]?\d+/y;
|
|
2561
2567
|
const functionNamePattern = /[a-z][a-z_0-9]*/y;
|
|
2562
2568
|
const indexPattern = /-?\d+/y;
|
|
2563
2569
|
const intPattern = /-?[0-9]+/y;
|
|
@@ -4000,7 +4006,7 @@ class Parser {
|
|
|
4000
4006
|
switch (stream.current.kind) {
|
|
4001
4007
|
case TokenKind.SINGLE_QUOTE_STRING:
|
|
4002
4008
|
case TokenKind.DOUBLE_QUOTE_STRING:
|
|
4003
|
-
items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current
|
|
4009
|
+
items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current), false));
|
|
4004
4010
|
break;
|
|
4005
4011
|
case TokenKind.FILTER:
|
|
4006
4012
|
items.push(this.parseFilter(stream));
|
|
@@ -4020,7 +4026,7 @@ class Parser {
|
|
|
4020
4026
|
break;
|
|
4021
4027
|
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
4022
4028
|
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
4023
|
-
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current
|
|
4029
|
+
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current), false));
|
|
4024
4030
|
break;
|
|
4025
4031
|
case TokenKind.KEYS_FILTER:
|
|
4026
4032
|
items.push(this.parseFilter(stream, true));
|
|
@@ -4036,6 +4042,7 @@ class Parser {
|
|
|
4036
4042
|
if (stream.peek.kind !== TokenKind.RBRACKET) {
|
|
4037
4043
|
stream.expectPeek(TokenKind.COMMA);
|
|
4038
4044
|
stream.next();
|
|
4045
|
+
stream.expectPeekNot(TokenKind.RBRACKET, "unexpected trailing comma");
|
|
4039
4046
|
}
|
|
4040
4047
|
stream.next();
|
|
4041
4048
|
}
|
|
@@ -4068,7 +4075,15 @@ class Parser {
|
|
|
4068
4075
|
return new StringLiteral(stream.current, this.decodeString(stream.current));
|
|
4069
4076
|
}
|
|
4070
4077
|
parseNumber(stream) {
|
|
4071
|
-
|
|
4078
|
+
const value = stream.current.value;
|
|
4079
|
+
if (value.startsWith("0") && value.length > 1) {
|
|
4080
|
+
throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
|
|
4081
|
+
}
|
|
4082
|
+
const num = Number(stream.current.value);
|
|
4083
|
+
if (isNaN(num)) {
|
|
4084
|
+
throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
|
|
4085
|
+
}
|
|
4086
|
+
return new NumberLiteral(stream.current, num);
|
|
4072
4087
|
}
|
|
4073
4088
|
parsePrefixExpression(stream) {
|
|
4074
4089
|
stream.expect(TokenKind.NOT);
|
|
@@ -4179,11 +4194,155 @@ class Parser {
|
|
|
4179
4194
|
return left;
|
|
4180
4195
|
}
|
|
4181
4196
|
decodeString(token) {
|
|
4182
|
-
|
|
4197
|
+
return this.unescapeString(token.kind === TokenKind.SINGLE_QUOTE_STRING ? token.value.replaceAll('"', '\\"').replaceAll("\\'", "'") : token.value, token);
|
|
4198
|
+
}
|
|
4199
|
+
unescapeString(value, token) {
|
|
4200
|
+
const rv = [];
|
|
4201
|
+
const length = value.length;
|
|
4202
|
+
let index = 0;
|
|
4203
|
+
let codepoint;
|
|
4204
|
+
while (index < length) {
|
|
4205
|
+
const ch = value[index];
|
|
4206
|
+
if (ch === "\\") {
|
|
4207
|
+
// Handle escape sequences
|
|
4208
|
+
index += 1; // Move past '\'
|
|
4209
|
+
|
|
4210
|
+
switch (value[index]) {
|
|
4211
|
+
case '"':
|
|
4212
|
+
rv.push('"');
|
|
4213
|
+
break;
|
|
4214
|
+
case "\\":
|
|
4215
|
+
rv.push("\\");
|
|
4216
|
+
break;
|
|
4217
|
+
case "/":
|
|
4218
|
+
rv.push("/");
|
|
4219
|
+
break;
|
|
4220
|
+
case "b":
|
|
4221
|
+
rv.push("\x08");
|
|
4222
|
+
break;
|
|
4223
|
+
case "f":
|
|
4224
|
+
rv.push("\x0C");
|
|
4225
|
+
break;
|
|
4226
|
+
case "n":
|
|
4227
|
+
rv.push("\n");
|
|
4228
|
+
break;
|
|
4229
|
+
case "r":
|
|
4230
|
+
rv.push("\r");
|
|
4231
|
+
break;
|
|
4232
|
+
case "t":
|
|
4233
|
+
rv.push("\t");
|
|
4234
|
+
break;
|
|
4235
|
+
case "u":
|
|
4236
|
+
[codepoint, index] = this.decodeHexChar(value, index, token);
|
|
4237
|
+
rv.push(this.stringFromCodePoint(codepoint, token));
|
|
4238
|
+
break;
|
|
4239
|
+
default:
|
|
4240
|
+
// TODO: This is unreachable. The lexer will catch unknown escape sequences.
|
|
4241
|
+
throw new JSONPathSyntaxError(`unknown escape sequence at index ${token.index + index - 1}`, token);
|
|
4242
|
+
}
|
|
4243
|
+
} else {
|
|
4244
|
+
this.stringFromCodePoint(ch.codePointAt(0), token);
|
|
4245
|
+
rv.push(ch);
|
|
4246
|
+
}
|
|
4247
|
+
index += 1;
|
|
4248
|
+
}
|
|
4249
|
+
return rv.join("");
|
|
4250
|
+
}
|
|
4251
|
+
|
|
4252
|
+
/**
|
|
4253
|
+
* Decode a `\uXXXX` or `\uXXXX\uXXXX` escape sequence from _value_ at _index_.
|
|
4254
|
+
*
|
|
4255
|
+
* @param value - A string value containing the sequence to decode.
|
|
4256
|
+
* @param index - The start index of an escape sequence in _value_.
|
|
4257
|
+
* @param token - The token for the string value.
|
|
4258
|
+
* @returns - A codepoint, new index tuple.
|
|
4259
|
+
*/
|
|
4260
|
+
decodeHexChar(value, index, token) {
|
|
4261
|
+
const length = value.length;
|
|
4262
|
+
if (index + 4 >= length) {
|
|
4263
|
+
throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 1}`, token);
|
|
4264
|
+
}
|
|
4265
|
+
index += 1; // Move past 'u'
|
|
4266
|
+
let codepoint = this.parseHexDigits(value.slice(index, index + 4), token);
|
|
4267
|
+
if (isLowSurrogate(codepoint)) {
|
|
4268
|
+
throw new JSONPathSyntaxError(`unexpected low surrogate codepoint at index ${token.index + index - 2}`, token);
|
|
4269
|
+
}
|
|
4270
|
+
if (isHighSurrogate(codepoint)) {
|
|
4271
|
+
// Expect a surrogate pair.
|
|
4272
|
+
if (!(index + 9 < length && value[index + 4] === "\\" && value[index + 5] === "u")) {
|
|
4273
|
+
throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 2}`, token);
|
|
4274
|
+
}
|
|
4275
|
+
const lowSurrogate = this.parseHexDigits(value.slice(index + 6, index + 10), token);
|
|
4276
|
+
if (!isLowSurrogate(lowSurrogate)) {
|
|
4277
|
+
throw new JSONPathSyntaxError(`unexpected codepoint at index ${token.index + index + 4}`, token);
|
|
4278
|
+
}
|
|
4279
|
+
codepoint = 0x10000 + ((codepoint & 0x03ff) << 10 | lowSurrogate & 0x03ff);
|
|
4280
|
+
return [codepoint, index + 9];
|
|
4281
|
+
}
|
|
4282
|
+
return [codepoint, index + 3];
|
|
4283
|
+
}
|
|
4284
|
+
|
|
4285
|
+
/**
|
|
4286
|
+
* Parse a hexadecimal string as an integer.
|
|
4287
|
+
*
|
|
4288
|
+
* @param digits - Hexadecimal digit string.
|
|
4289
|
+
* @param token - The token for the string value.
|
|
4290
|
+
* @returns - The number representation of _digits_.
|
|
4291
|
+
*
|
|
4292
|
+
* Note that we're not using `parseInt(digits, 16)` because it accepts `+`
|
|
4293
|
+
* and `-` and things we don't allow.
|
|
4294
|
+
*/
|
|
4295
|
+
parseHexDigits(digits, token) {
|
|
4296
|
+
const encoder = new TextEncoder();
|
|
4297
|
+
let codepoint = 0;
|
|
4298
|
+
for (const digit of encoder.encode(digits)) {
|
|
4299
|
+
codepoint <<= 4;
|
|
4300
|
+
switch (digit) {
|
|
4301
|
+
case 48:
|
|
4302
|
+
case 49:
|
|
4303
|
+
case 50:
|
|
4304
|
+
case 51:
|
|
4305
|
+
case 52:
|
|
4306
|
+
case 53:
|
|
4307
|
+
case 54:
|
|
4308
|
+
case 55:
|
|
4309
|
+
case 56:
|
|
4310
|
+
case 57:
|
|
4311
|
+
codepoint |= digit - 48; // '0'
|
|
4312
|
+
break;
|
|
4313
|
+
case 97:
|
|
4314
|
+
case 98:
|
|
4315
|
+
case 99:
|
|
4316
|
+
case 100:
|
|
4317
|
+
case 101:
|
|
4318
|
+
case 102:
|
|
4319
|
+
codepoint |= digit - 97 + 10; // 'a'
|
|
4320
|
+
break;
|
|
4321
|
+
case 65:
|
|
4322
|
+
case 66:
|
|
4323
|
+
case 67:
|
|
4324
|
+
case 68:
|
|
4325
|
+
case 69:
|
|
4326
|
+
case 70:
|
|
4327
|
+
codepoint |= digit - 65 + 10; // 'A'
|
|
4328
|
+
break;
|
|
4329
|
+
default:
|
|
4330
|
+
throw new JSONPathSyntaxError("invalid \\uXXXX escape sequence", token);
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
return codepoint;
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4336
|
+
/** Check the codepoint is valid and return its string representation. */
|
|
4337
|
+
stringFromCodePoint(codepoint, token) {
|
|
4338
|
+
if (codepoint === undefined || codepoint <= 0x1f) {
|
|
4339
|
+
throw new JSONPathSyntaxError(`invalid character`, token);
|
|
4340
|
+
}
|
|
4183
4341
|
try {
|
|
4184
|
-
return
|
|
4342
|
+
return String.fromCodePoint(codepoint);
|
|
4185
4343
|
} catch {
|
|
4186
|
-
|
|
4344
|
+
// This should not be reachable.
|
|
4345
|
+
throw new JSONPathSyntaxError("invalid escape sequence", token);
|
|
4187
4346
|
}
|
|
4188
4347
|
}
|
|
4189
4348
|
throwForNonComparable(expr) {
|
|
@@ -4203,6 +4362,12 @@ class Parser {
|
|
|
4203
4362
|
}
|
|
4204
4363
|
}
|
|
4205
4364
|
}
|
|
4365
|
+
function isHighSurrogate(codepoint) {
|
|
4366
|
+
return codepoint >= 0xd800 && codepoint <= 0xdbff;
|
|
4367
|
+
}
|
|
4368
|
+
function isLowSurrogate(codepoint) {
|
|
4369
|
+
return codepoint >= 0xdc00 && codepoint <= 0xdfff;
|
|
4370
|
+
}
|
|
4206
4371
|
|
|
4207
4372
|
/**
|
|
4208
4373
|
* JSONPath environment options. The defaults are in compliance with JSONPath
|
|
@@ -4260,7 +4425,7 @@ class JSONPathEnvironment {
|
|
|
4260
4425
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
4261
4426
|
this.strict = options.strict ?? true;
|
|
4262
4427
|
this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
|
|
4263
|
-
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53)
|
|
4428
|
+
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) + 1;
|
|
4264
4429
|
this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
|
|
4265
4430
|
this.nondeterministic = options.nondeterministic ?? false;
|
|
4266
4431
|
this.keysPattern = options.keysPattern ?? /~/y;
|
|
@@ -4984,6 +5149,6 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4984
5149
|
apply: apply
|
|
4985
5150
|
});
|
|
4986
5151
|
|
|
4987
|
-
const version = "1.3.
|
|
5152
|
+
const version = "1.3.4";
|
|
4988
5153
|
|
|
4989
5154
|
export { DEFAULT_ENVIRONMENT, FunctionExpressionType, JSONPatch, JSONPatchError, JSONPatchTestFailure, JSONPath, JSONPathEnvironment, JSONPathError, JSONPathIndexError, JSONPathLexerError, JSONPathNode, JSONPathNodeList, JSONPathRecursionLimitError, JSONPathSyntaxError, JSONPathTypeError, JSONPointer, Nothing, RelativeJSONPointer, Token, TokenKind, UNDEFINED, apply, compile, index as jsonpatch, index$1 as jsonpath, index$3 as jsonpointer, lazyQuery, query, resolve, version };
|