whatwg-url 4.5.1 → 4.8.0
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/README.md +1 -1
- package/lib/url-state-machine.js +91 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ whatwg-url is a full implementation of the WHATWG [URL Standard](https://url.spe
|
|
|
4
4
|
|
|
5
5
|
## Current Status
|
|
6
6
|
|
|
7
|
-
whatwg-url is currently up to date with the URL spec up to commit [
|
|
7
|
+
whatwg-url is currently up to date with the URL spec up to commit [fe6b25](https://github.com/whatwg/url/commit/fe6b251739e225555f04319f19c70c031a5d99eb).
|
|
8
8
|
|
|
9
9
|
## API
|
|
10
10
|
|
package/lib/url-state-machine.js
CHANGED
|
@@ -179,6 +179,9 @@ function parseIPv4(input) {
|
|
|
179
179
|
|
|
180
180
|
const numbers = [];
|
|
181
181
|
for (const part of parts) {
|
|
182
|
+
if (part === "") {
|
|
183
|
+
return input;
|
|
184
|
+
}
|
|
182
185
|
const n = parseIPv4Number(part);
|
|
183
186
|
if (n === failure) {
|
|
184
187
|
return input;
|
|
@@ -240,8 +243,6 @@ function parseIPv6(input) {
|
|
|
240
243
|
compressPtr = piecePtr;
|
|
241
244
|
}
|
|
242
245
|
|
|
243
|
-
let ipv4 = false;
|
|
244
|
-
Main:
|
|
245
246
|
while (pointer < input.length) {
|
|
246
247
|
if (piecePtr === 8) {
|
|
247
248
|
return failure;
|
|
@@ -266,77 +267,74 @@ function parseIPv6(input) {
|
|
|
266
267
|
++length;
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (length === 0) {
|
|
272
|
-
return failure;
|
|
273
|
-
}
|
|
274
|
-
pointer -= length;
|
|
275
|
-
ipv4 = true;
|
|
276
|
-
break Main;
|
|
277
|
-
case ":":
|
|
278
|
-
++pointer;
|
|
279
|
-
if (input[pointer] === undefined) {
|
|
280
|
-
return failure;
|
|
281
|
-
}
|
|
282
|
-
break;
|
|
283
|
-
case undefined:
|
|
284
|
-
break;
|
|
285
|
-
default:
|
|
270
|
+
if (input[pointer] === 46) {
|
|
271
|
+
if (length === 0) {
|
|
286
272
|
return failure;
|
|
287
|
-
|
|
273
|
+
}
|
|
288
274
|
|
|
289
|
-
|
|
290
|
-
++piecePtr;
|
|
291
|
-
}
|
|
275
|
+
pointer -= length;
|
|
292
276
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
let numbersSeen = 0;
|
|
277
|
+
if (piecePtr > 6) {
|
|
278
|
+
return failure;
|
|
279
|
+
}
|
|
297
280
|
|
|
298
|
-
|
|
299
|
-
let value = null;
|
|
281
|
+
let numbersSeen = 0;
|
|
300
282
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
++pointer;
|
|
304
|
-
} else {
|
|
305
|
-
return failure;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
283
|
+
while (input[pointer] !== undefined) {
|
|
284
|
+
let ipv4Piece = null;
|
|
308
285
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
286
|
+
if (numbersSeen > 0) {
|
|
287
|
+
if (input[pointer] === 46 && numbersSeen < 4) {
|
|
288
|
+
++pointer;
|
|
289
|
+
} else {
|
|
290
|
+
return failure;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
312
293
|
|
|
313
|
-
|
|
314
|
-
const number = parseInt(at(input, pointer));
|
|
315
|
-
if (value === null) {
|
|
316
|
-
value = number;
|
|
317
|
-
} else if (value === 0) {
|
|
294
|
+
if (!isASCIIDigit(input[pointer])) {
|
|
318
295
|
return failure;
|
|
319
|
-
} else {
|
|
320
|
-
value = value * 10 + number;
|
|
321
296
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
297
|
+
|
|
298
|
+
while (isASCIIDigit(input[pointer])) {
|
|
299
|
+
const number = parseInt(at(input, pointer));
|
|
300
|
+
if (ipv4Piece === null) {
|
|
301
|
+
ipv4Piece = number;
|
|
302
|
+
} else if (ipv4Piece === 0) {
|
|
303
|
+
return failure;
|
|
304
|
+
} else {
|
|
305
|
+
ipv4Piece = ipv4Piece * 10 + number;
|
|
306
|
+
}
|
|
307
|
+
if (ipv4Piece > 255) {
|
|
308
|
+
return failure;
|
|
309
|
+
}
|
|
310
|
+
++pointer;
|
|
325
311
|
}
|
|
326
|
-
}
|
|
327
312
|
|
|
328
|
-
|
|
313
|
+
ip[piecePtr] = ip[piecePtr] * 0x100 + ipv4Piece;
|
|
314
|
+
|
|
315
|
+
++numbersSeen;
|
|
329
316
|
|
|
330
|
-
|
|
317
|
+
if (numbersSeen === 2 || numbersSeen === 4) {
|
|
318
|
+
++piecePtr;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
331
321
|
|
|
332
|
-
if (numbersSeen
|
|
333
|
-
|
|
322
|
+
if (numbersSeen !== 4) {
|
|
323
|
+
return failure;
|
|
334
324
|
}
|
|
335
325
|
|
|
336
|
-
|
|
326
|
+
break;
|
|
327
|
+
} else if (input[pointer] === 58) {
|
|
328
|
+
++pointer;
|
|
329
|
+
if (input[pointer] === undefined) {
|
|
337
330
|
return failure;
|
|
338
331
|
}
|
|
332
|
+
} else if (input[pointer] !== undefined) {
|
|
333
|
+
return failure;
|
|
339
334
|
}
|
|
335
|
+
|
|
336
|
+
ip[piecePtr] = value;
|
|
337
|
+
++piecePtr;
|
|
340
338
|
}
|
|
341
339
|
|
|
342
340
|
if (compressPtr !== null) {
|
|
@@ -349,7 +347,7 @@ function parseIPv6(input) {
|
|
|
349
347
|
--piecePtr;
|
|
350
348
|
--swaps;
|
|
351
349
|
}
|
|
352
|
-
} else if (piecePtr !== 8) {
|
|
350
|
+
} else if (compressPtr === null && piecePtr !== 8) {
|
|
353
351
|
return failure;
|
|
354
352
|
}
|
|
355
353
|
|
|
@@ -360,20 +358,26 @@ function serializeIPv6(address) {
|
|
|
360
358
|
let output = "";
|
|
361
359
|
const seqResult = findLongestZeroSequence(address);
|
|
362
360
|
const compressPtr = seqResult.idx;
|
|
361
|
+
let ignore0 = false;
|
|
363
362
|
|
|
364
363
|
for (let i = 0; i < address.length; ++i) {
|
|
365
|
-
|
|
366
|
-
if (i === 0) {
|
|
367
|
-
output += "::";
|
|
368
|
-
} else {
|
|
369
|
-
output += ":";
|
|
370
|
-
}
|
|
364
|
+
const piece = address[i];
|
|
371
365
|
|
|
372
|
-
|
|
366
|
+
if (ignore0 && piece === 0) {
|
|
373
367
|
continue;
|
|
368
|
+
} else if (ignore0) {
|
|
369
|
+
ignore0 = false;
|
|
374
370
|
}
|
|
375
371
|
|
|
376
|
-
|
|
372
|
+
if (compressPtr === i) {
|
|
373
|
+
const separator = i === 0 ? "::" : ":";
|
|
374
|
+
output += separator;
|
|
375
|
+
ignore0 = true;
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
output += piece.toString(16);
|
|
380
|
+
|
|
377
381
|
if (i !== address.length - 1) {
|
|
378
382
|
output += ":";
|
|
379
383
|
}
|
|
@@ -594,6 +598,14 @@ URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) {
|
|
|
594
598
|
if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {
|
|
595
599
|
return false;
|
|
596
600
|
}
|
|
601
|
+
|
|
602
|
+
if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
597
609
|
}
|
|
598
610
|
this.url.scheme = this.buffer;
|
|
599
611
|
this.buffer = "";
|
|
@@ -916,9 +928,10 @@ URLStateMachine.prototype["parse file"] = function parseFile(c) {
|
|
|
916
928
|
this.url.fragment = "";
|
|
917
929
|
this.state = "fragment";
|
|
918
930
|
} else {
|
|
919
|
-
if (
|
|
920
|
-
this.input
|
|
921
|
-
|
|
931
|
+
if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points
|
|
932
|
+
!isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||
|
|
933
|
+
(this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points
|
|
934
|
+
!fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {
|
|
922
935
|
this.url.host = this.base.host;
|
|
923
936
|
this.url.path = this.base.path.slice();
|
|
924
937
|
shortenPath(this.url);
|
|
@@ -945,8 +958,10 @@ URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) {
|
|
|
945
958
|
this.state = "file host";
|
|
946
959
|
} else {
|
|
947
960
|
if (this.base !== null && this.base.scheme === "file") {
|
|
948
|
-
if (
|
|
961
|
+
if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {
|
|
949
962
|
this.url.path.push(this.base.path[0]);
|
|
963
|
+
} else {
|
|
964
|
+
this.url.host = this.base.host;
|
|
950
965
|
}
|
|
951
966
|
}
|
|
952
967
|
this.state = "path";
|
|
@@ -1035,15 +1050,21 @@ URLStateMachine.prototype["parse path"] = function parsePath(c) {
|
|
|
1035
1050
|
this.url.path.push("");
|
|
1036
1051
|
} else if (!isSingleDot(this.buffer)) {
|
|
1037
1052
|
if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {
|
|
1038
|
-
if (this.url.host !== null) {
|
|
1053
|
+
if (this.url.host !== "" && this.url.host !== null) {
|
|
1039
1054
|
this.parseError = true;
|
|
1055
|
+
this.url.host = "";
|
|
1040
1056
|
}
|
|
1041
|
-
this.url.host = null;
|
|
1042
1057
|
this.buffer = this.buffer[0] + ":";
|
|
1043
1058
|
}
|
|
1044
1059
|
this.url.path.push(this.buffer);
|
|
1045
1060
|
}
|
|
1046
1061
|
this.buffer = "";
|
|
1062
|
+
if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) {
|
|
1063
|
+
while (this.url.path.length > 1 && this.url.path[0] === "") {
|
|
1064
|
+
this.parseError = true;
|
|
1065
|
+
this.url.path.shift();
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1047
1068
|
if (c === 63) {
|
|
1048
1069
|
this.url.query = "";
|
|
1049
1070
|
this.state = "query";
|