(url)
| 1508 | } |
| 1509 | |
| 1510 | function getPathBufferFromURLWin32(url) { |
| 1511 | const hostname = url.hostname; |
| 1512 | let pathname = url.pathname; |
| 1513 | // In the getPathFromURLWin32 variant, we scan the input for backslash (\) |
| 1514 | // and forward slash (/) characters, specifically looking for the ASCII/UTF8 |
| 1515 | // encoding these and forbidding their use. This is a bit tricky |
| 1516 | // because these may conflict with non-UTF8 encodings. For instance, |
| 1517 | // in shift-jis, %5C identifies the symbol for the Japanese Yen and not the |
| 1518 | // backslash. If we have a url like file:///foo/%5c/bar, then we really have |
| 1519 | // no way of knowing if that %5c is meant to be a backslash \ or a yen sign. |
| 1520 | // Passing in an encoding option does not help since our Buffer encoding only |
| 1521 | // knows about certain specific text encodings and a single file path might |
| 1522 | // actually contain segments that use multiple encodings. It's tricky! So, |
| 1523 | // for this variation where we are producing a buffer, we won't scan for the |
| 1524 | // slashes at all, and instead will decode the bytes literally into the |
| 1525 | // returned Buffer. That said, that can also be tricky because, on windows, |
| 1526 | // the file path separator *is* the ASCII backslash. This is a known issue |
| 1527 | // on windows specific to the Shift-JIS encoding that we're not really going |
| 1528 | // to solve here. Instead, we're going to do the best we can and just |
| 1529 | // interpret the input url as a sequence of bytes. |
| 1530 | |
| 1531 | // Because we are converting to a Windows file path here, we need to replace |
| 1532 | // the explicit forward slash separators with backslashes. Note that this |
| 1533 | // intentionally disregards any percent-encoded forward slashes in the path. |
| 1534 | pathname = SideEffectFreeRegExpPrototypeSymbolReplace(FORWARD_SLASH, pathname, '\\'); |
| 1535 | |
| 1536 | // Now, let's start to build our Buffer. We will initially start with a |
| 1537 | // Buffer allocated to fit in the entire string. Worst case there are no |
| 1538 | // percent encoded characters and we take the string as is. Any invalid |
| 1539 | // percent encodings, e.g. `%ZZ` are ignored and are passed through |
| 1540 | // literally. |
| 1541 | const decodedu8 = percentDecode(Buffer.from(pathname, 'utf8')); |
| 1542 | const decodedPathname = Buffer.from(TypedArrayPrototypeGetBuffer(decodedu8), |
| 1543 | TypedArrayPrototypeGetByteOffset(decodedu8), |
| 1544 | TypedArrayPrototypeGetByteLength(decodedu8)); |
| 1545 | if (hostname !== '') { |
| 1546 | // If hostname is set, then we have a UNC path |
| 1547 | // Pass the hostname through domainToUnicode just in case |
| 1548 | // it is an IDN using punycode encoding. We do not need to worry |
| 1549 | // about percent encoding because the URL parser will have |
| 1550 | // already taken care of that for us. Note that this only |
| 1551 | // causes IDNs with an appropriate `xn--` prefix to be decoded. |
| 1552 | |
| 1553 | // This is a bit tricky because of the need to convert to a Buffer |
| 1554 | // followed by concatenation of the results. |
| 1555 | const prefix = Buffer.from('\\\\', 'ascii'); |
| 1556 | const domain = Buffer.from(domainToUnicode(hostname), 'utf8'); |
| 1557 | |
| 1558 | return Buffer.concat([prefix, domain, decodedPathname]); |
| 1559 | } |
| 1560 | // Otherwise, it's a local path that requires a drive letter |
| 1561 | // In this case we're only going to pay attention to the second and |
| 1562 | // third bytes in the decodedPathname. If first byte is either an ASCII |
| 1563 | // uppercase letter between 'A' and 'Z' or lowercase letter between |
| 1564 | // 'a' and 'z', and the second byte must be an ASCII `:` or the |
| 1565 | // operation will fail. |
| 1566 | |
| 1567 | const letter = decodedPathname[1] | 0x20; |
no test coverage detected
searching dependent graphs…