| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1068,62 +1068,64 @@ The resolver can throw the following errors: | |||
| 1068 | 1068 | > 1. Note: _specifier_ is now a bare specifier. | |
| 1069 | 1069 | > 2. Set _resolved_ the result of | |
| 1070 | 1070 | > **PACKAGE\_RESOLVE**(_specifier_, _parentURL_). | |
| 1071 | - > 6. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2f"_ | ||
| 1072 | - > and _"%5C"_ respectively), then | ||
| 1073 | - > 1. Throw an _Invalid Module Specifier_ error. | ||
| 1074 | - > 7. If the file at _resolved_ is a directory, then | ||
| 1075 | - > 1. Throw an _Unsupported Directory Import_ error. | ||
| 1076 | - > 8. If the file at _resolved_ does not exist, then | ||
| 1077 | - > 1. Throw a _Module Not Found_ error. | ||
| 1078 | - > 9. Set _resolved_ to the real path of _resolved_. | ||
| 1079 | - > 10. Let _format_ be the result of **ESM\_FORMAT**(_resolved_). | ||
| 1080 | - > 11. Load _resolved_ as module format, _format_. | ||
| 1081 | - > 12. Return _resolved_. | ||
| 1071 | + > 6. Let _format_ be **undefined**. | ||
| 1072 | + > 7. If _resolved_ is a _"file:"_ URL, then | ||
| 1073 | + > 1. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2F"_ | ||
| 1074 | + > and _"%5C"_ respectively), then | ||
| 1075 | + > 1. Throw an _Invalid Module Specifier_ error. | ||
| 1076 | + > 2. If the file at _resolved_ is a directory, then | ||
| 1077 | + > 1. Throw an _Unsupported Directory Import_ error. | ||
| 1078 | + > 3. If the file at _resolved_ does not exist, then | ||
| 1079 | + > 1. Throw a _Module Not Found_ error. | ||
| 1080 | + > 4. Set _resolved_ to the real path of _resolved_, maintaining the | ||
| 1081 | + > same URL querystring and fragment components. | ||
| 1082 | + > 5. Set _format_ to the result of **ESM\_FILE\_FORMAT**(_resolved_). | ||
| 1083 | + > 8. Otherwise, | ||
| 1084 | + > 1. Set _format_ the module format of the content type associated with the | ||
| 1085 | + > URL _resolved_. | ||
| 1086 | + > 9. Load _resolved_ as module format, _format_. | ||
| 1082 | 1087 | ||
| 1083 | 1088 | **PACKAGE\_RESOLVE**(_packageSpecifier_, _parentURL_) | |
| 1084 | 1089 | ||
| 1085 | 1090 | > 1. Let _packageName_ be **undefined**. | |
| 1086 | 1091 | > 2. If _packageSpecifier_ is an empty string, then | |
| 1087 | 1092 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1088 | - > 3. If _packageSpecifier_ does not start with _"@"_, then | ||
| 1093 | + > 3. If _packageSpecifier_ is a Node.js builtin module name, then | ||
| 1094 | + > 1. Return the string _"node:"_ concatenated with _packageSpecifier_. | ||
| 1095 | + > 4. If _packageSpecifier_ does not start with _"@"_, then | ||
| 1089 | 1096 | > 1. Set _packageName_ to the substring of _packageSpecifier_ until the first | |
| 1090 | 1097 | > _"/"_ separator or the end of the string. | |
| 1091 | - > 4. Otherwise, | ||
| 1098 | + > 5. Otherwise, | ||
| 1092 | 1099 | > 1. If _packageSpecifier_ does not contain a _"/"_ separator, then | |
| 1093 | 1100 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1094 | 1101 | > 2. Set _packageName_ to the substring of _packageSpecifier_ | |
| 1095 | 1102 | > until the second _"/"_ separator or the end of the string. | |
| 1096 | - > 5. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then | ||
| 1103 | + > 6. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then | ||
| 1097 | 1104 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1098 | - > 6. Let _packageSubpath_ be _"."_ concatenated with the substring of | ||
| 1105 | + > 7. Let _packageSubpath_ be _"."_ concatenated with the substring of | ||
| 1099 | 1106 | > _packageSpecifier_ from the position at the length of _packageName_. | |
| 1100 | - > 7. Let _selfUrl_ be the result of | ||
| 1107 | + > 8. If _packageSubpath_ ends in _"/"_, then | ||
| 1108 | + > 1. Throw an _Invalid Module Specifier_ error. | ||
| 1109 | + > 9. Let _selfUrl_ be the result of | ||
| 1101 | 1110 | > **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_). | |
| 1102 | - > 8. If _selfUrl_ is not **undefined**, return _selfUrl_. | ||
| 1103 | - > 9. If _packageSubpath_ is _"."_ and _packageName_ is a Node.js builtin | ||
| 1104 | - > module, then | ||
| 1105 | - > 1. Return the string _"node:"_ concatenated with _packageSpecifier_. | ||
| 1106 | - > 10. While _parentURL_ is not the file system root, | ||
| 1107 | - > 1. Let _packageURL_ be the URL resolution of _"node\_modules/"_ | ||
| 1108 | - > concatenated with _packageSpecifier_, relative to _parentURL_. | ||
| 1109 | - > 2. Set _parentURL_ to the parent folder URL of _parentURL_. | ||
| 1110 | - > 3. If the folder at _packageURL_ does not exist, then | ||
| 1111 | - > 1. Set _parentURL_ to the parent URL path of _parentURL_. | ||
| 1112 | - > 2. Continue the next loop iteration. | ||
| 1113 | - > 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). | ||
| 1114 | - > 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or | ||
| 1115 | - > **undefined**, then | ||
| 1116 | - > 1. Let _exports_ be _pjson.exports_. | ||
| 1117 | - > 2. Return the _resolved_ destructured value of the result of | ||
| 1118 | - > **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, _packageSubpath_, | ||
| 1119 | - > _pjson.exports_, _defaultConditions_). | ||
| 1120 | - > 6. Otherwise, if _packageSubpath_ is equal to _"."_, then | ||
| 1121 | - > 1. Return the result applying the legacy **LOAD\_AS\_DIRECTORY** | ||
| 1122 | - > CommonJS resolver to _packageURL_, throwing a _Module Not Found_ | ||
| 1123 | - > error for no resolution. | ||
| 1124 | - > 7. Otherwise, | ||
| 1125 | - > 1. Return the URL resolution of _packageSubpath_ in _packageURL_. | ||
| 1126 | - > 11. Throw a _Module Not Found_ error. | ||
| 1111 | + > 10. If _selfUrl_ is not **undefined**, return _selfUrl_. | ||
| 1112 | + > 11. While _parentURL_ is not the file system root, | ||
| 1113 | + > 1. Let _packageURL_ be the URL resolution of _"node_modules/"_ | ||
| 1114 | + > concatenated with _packageSpecifier_, relative to _parentURL_. | ||
| 1115 | + > 2. Set _parentURL_ to the parent folder URL of _parentURL_. | ||
| 1116 | + > 3. If the folder at _packageURL_ does not exist, then | ||
| 1117 | + > 1. Continue the next loop iteration. | ||
| 1118 | + > 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). | ||
| 1119 | + > 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or | ||
| 1120 | + > **undefined**, then | ||
| 1121 | + > 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, | ||
| 1122 | + > _packageSubpath_, _pjson.exports_, _defaultConditions_). | ||
| 1123 | + > 6. Otherwise, if _packageSubpath_ is equal to _"."_, then | ||
| 1124 | + > 1. If _pjson.main_ is a string, then | ||
| 1125 | + > 1. Return the URL resolution of _main_ in _packageURL_. | ||
| 1126 | + > 7. Otherwise, | ||
| 1127 | + > 1. Return the URL resolution of _packageSubpath_ in _packageURL_. | ||
| 1128 | + > 12. Throw a _Module Not Found_ error. | ||
| 1127 | 1129 | ||
| 1128 | 1130 | **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_) | |
| 1129 | 1131 | ||
@@ -1253,18 +1255,20 @@ _internal_, _conditions_) | |||
| 1253 | 1255 | > _"/"_ and is not a valid URL, then | |
| 1254 | 1256 | > 1. If _pattern_ is **true**, then | |
| 1255 | 1257 | > 1. Return **PACKAGE\_RESOLVE**(_target_ with every instance of | |
| 1256 | - > _"\*"_ replaced by _subpath_, _packageURL_ + _"/"_)\_. | ||
| 1258 | + > _"\*"_ replaced by _subpath_, _packageURL_ + _"/"_). | ||
| 1257 | 1259 | > 2. Return **PACKAGE\_RESOLVE**(_target_ + _subpath_, | |
| 1258 | - > _packageURL_ + _"/"_)\_. | ||
| 1260 | + > _packageURL_ + _"/"_)_. | ||
| 1259 | 1261 | > 2. Otherwise, throw an _Invalid Package Target_ error. | |
| 1260 | 1262 | > 3. If _target_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or | |
| 1261 | - > _"node\_modules"_ segments after the first segment, throw an | ||
| 1262 | - > _Invalid Package Target_ error. | ||
| 1263 | + > _"node\_modules"_ segments after the first segment, case insensitive and | ||
| 1264 | + > including percent encoded variants, throw an _Invalid Package Target_ | ||
| 1265 | + > error. | ||
| 1263 | 1266 | > 4. Let _resolvedTarget_ be the URL resolution of the concatenation of | |
| 1264 | 1267 | > _packageURL_ and _target_. | |
| 1265 | 1268 | > 5. Assert: _resolvedTarget_ is contained in _packageURL_. | |
| 1266 | 1269 | > 6. If _subpath_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or | |
| 1267 | - > _"node\_modules"_ segments, throw an _Invalid Module Specifier_ error. | ||
| 1270 | + > _"node\_modules"_ segments, case insensitive and including percent | ||
| 1271 | + > encoded variants, throw an _Invalid Module Specifier_ error. | ||
| 1268 | 1272 | > 7. If _pattern_ is **true**, then | |
| 1269 | 1273 | > 1. Return the URL resolution of _resolvedTarget_ with every instance of | |
| 1270 | 1274 | > _"\*"_ replaced with _subpath_. | |
@@ -1297,19 +1301,21 @@ _internal_, _conditions_) | |||
| 1297 | 1301 | > 4. Otherwise, if _target_ is _null_, return **null**. | |
| 1298 | 1302 | > 5. Otherwise throw an _Invalid Package Target_ error. | |
| 1299 | 1303 | ||
| 1300 | - **ESM\_FORMAT**(_url_) | ||
| 1304 | + **ESM\_FILE\_FORMAT**(_url_) | ||
| 1301 | 1305 | ||
| 1302 | 1306 | > 1. Assert: _url_ corresponds to an existing file. | |
| 1303 | 1307 | > 2. Let _pjson_ be the result of **READ\_PACKAGE\_SCOPE**(_url_). | |
| 1304 | 1308 | > 3. If _url_ ends in _".mjs"_, then | |
| 1305 | 1309 | > 1. Return _"module"_. | |
| 1306 | 1310 | > 4. If _url_ ends in _".cjs"_, then | |
| 1307 | 1311 | > 1. Return _"commonjs"_. | |
| 1308 | - > 5. If _pjson?.type_ exists and is _"module"_, then | ||
| 1312 | + > 5. If _url_ ends in _".json"_, then | ||
| 1313 | + > 1. Return _"json"_. | ||
| 1314 | + > 6. If _pjson?.type_ exists and is _"module"_, then | ||
| 1309 | 1315 | > 1. If _url_ ends in _".js"_, then | |
| 1310 | 1316 | > 1. Return _"module"_. | |
| 1311 | 1317 | > 2. Throw an _Unsupported File Extension_ error. | |
| 1312 | - > 6. Otherwise, | ||
| 1318 | + > 7. Otherwise, | ||
| 1313 | 1319 | > 1. Throw an _Unsupported File Extension_ error. | |
| 1314 | 1320 | ||
| 1315 | 1321 | **READ\_PACKAGE\_SCOPE**(_url_) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ const { | |||
| 10 | 10 | ObjectGetOwnPropertyNames, | |
| 11 | 11 | ObjectPrototypeHasOwnProperty, | |
| 12 | 12 | RegExp, | |
| 13 | + RegExpPrototypeExec, | ||
| 13 | 14 | RegExpPrototypeSymbolReplace, | |
| 14 | 15 | RegExpPrototypeTest, | |
| 15 | 16 | SafeMap, | |
@@ -384,9 +385,10 @@ const encodedSepRegEx = /%2F|%5C/i; | |||
| 384 | 385 | /** | |
| 385 | 386 | * @param {URL} resolved | |
| 386 | 387 | * @param {string | URL | undefined} base | |
| 388 | + * @param {boolean} preserveSymlinks | ||
| 387 | 389 | * @returns {URL | undefined} | |
| 388 | 390 | */ | |
| 389 | - function finalizeResolution(resolved, base) { | ||
| 391 | + function finalizeResolution(resolved, base, preserveSymlinks) { | ||
| 390 | 392 | if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) | |
| 391 | 393 | throw new ERR_INVALID_MODULE_SPECIFIER( | |
| 392 | 394 | resolved.pathname, 'must not include encoded "/" or "\\" characters', | |
@@ -417,6 +419,17 @@ function finalizeResolution(resolved, base) { | |||
| 417 | 419 | path || resolved.pathname, base && fileURLToPath(base), 'module'); | |
| 418 | 420 | } | |
| 419 | 421 | ||
| 422 | + if (!preserveSymlinks) { | ||
| 423 | + const real = realpathSync(path, { | ||
| 424 | + [internalFS.realpathCacheKey]: realpathCache | ||
| 425 | + }); | ||
| 426 | + const { search, hash } = resolved; | ||
| 427 | + resolved = | ||
| 428 | + pathToFileURL(real + (StringPrototypeEndsWith(path, sep) ? '/' : '')); | ||
| 429 | + resolved.search = search; | ||
| 430 | + resolved.hash = hash; | ||
| 431 | + } | ||
| 432 | + | ||
| 420 | 433 | return resolved; | |
| 421 | 434 | } | |
| 422 | 435 | ||
@@ -468,7 +481,8 @@ function throwInvalidPackageTarget( | |||
| 468 | 481 | internal, base && fileURLToPath(base)); | |
| 469 | 482 | } | |
| 470 | 483 | ||
| 471 | - const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; | ||
| 484 | + const invalidSegmentRegEx = /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i; | ||
| 485 | + const invalidPackageNameRegEx = /^\.|%|\\/; | ||
| 472 | 486 | const patternRegEx = /\*/g; | |
| 473 | 487 | ||
| 474 | 488 | function resolvePackageTargetString( | |
@@ -810,13 +824,9 @@ function parsePackageName(specifier, base) { | |||
| 810 | 824 | specifier : StringPrototypeSlice(specifier, 0, separatorIndex); | |
| 811 | 825 | ||
| 812 | 826 | // Package name cannot have leading . and cannot have percent-encoding or | |
| 813 | - // separators. | ||
| 814 | - for (let i = 0; i < packageName.length; i++) { | ||
| 815 | - if (packageName[i] === '%' || packageName[i] === '\\') { | ||
| 816 | - validPackageName = false; | ||
| 817 | - break; | ||
| 818 | - } | ||
| 819 | - } | ||
| 827 | + // \\ separators. | ||
| 828 | + if (RegExpPrototypeExec(invalidPackageNameRegEx, packageName) !== null) | ||
| 829 | + validPackageName = false; | ||
| 820 | 830 | ||
| 821 | 831 | if (!validPackageName) { | |
| 822 | 832 | throw new ERR_INVALID_MODULE_SPECIFIER( | |
@@ -836,6 +846,9 @@ function parsePackageName(specifier, base) { | |||
| 836 | 846 | * @returns {URL} | |
| 837 | 847 | */ | |
| 838 | 848 | function packageResolve(specifier, base, conditions) { | |
| 849 | + if (NativeModule.canBeRequiredByUsers(specifier)) | ||
| 850 | + return new URL('node:' + specifier); | ||
| 851 | + | ||
| 839 | 852 | const { packageName, packageSubpath, isScoped } = | |
| 840 | 853 | parsePackageName(specifier, base); | |
| 841 | 854 | ||
@@ -912,9 +925,10 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { | |||
| 912 | 925 | * @param {string} specifier | |
| 913 | 926 | * @param {string | URL | undefined} base | |
| 914 | 927 | * @param {Set<string>} conditions | |
| 928 | + * @param {boolean} preserveSymlinks | ||
| 915 | 929 | * @returns {URL} | |
| 916 | 930 | */ | |
| 917 | - function moduleResolve(specifier, base, conditions) { | ||
| 931 | + function moduleResolve(specifier, base, conditions, preserveSymlinks) { | ||
| 918 | 932 | // Order swapped from spec for minor perf gain. | |
| 919 | 933 | // Ok since relative URLs cannot parse as URLs. | |
| 920 | 934 | let resolved; | |
@@ -929,7 +943,9 @@ function moduleResolve(specifier, base, conditions) { | |||
| 929 | 943 | resolved = packageResolve(specifier, base, conditions); | |
| 930 | 944 | } | |
| 931 | 945 | } | |
| 932 | - return finalizeResolution(resolved, base); | ||
| 946 | + if (resolved.protocol !== 'file:') | ||
| 947 | + return resolved; | ||
| 948 | + return finalizeResolution(resolved, base, preserveSymlinks); | ||
| 933 | 949 | } | |
| 934 | 950 | ||
| 935 | 951 | /** | |
@@ -1001,28 +1017,6 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 1001 | 1017 | } | |
| 1002 | 1018 | } | |
| 1003 | 1019 | } | |
| 1004 | - let parsed; | ||
| 1005 | - try { | ||
| 1006 | - parsed = new URL(specifier); | ||
| 1007 | - if (parsed.protocol === 'data:') { | ||
| 1008 | - return { | ||
| 1009 | - url: specifier | ||
| 1010 | - }; | ||
| 1011 | - } | ||
| 1012 | - } catch {} | ||
| 1013 | - if (parsed && parsed.protocol === 'node:') | ||
| 1014 | - return { url: specifier }; | ||
| 1015 | - if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') | ||
| 1016 | - throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed); | ||
| 1017 | - if (NativeModule.canBeRequiredByUsers(specifier)) { | ||
| 1018 | - return { | ||
| 1019 | - url: 'node:' + specifier | ||
| 1020 | - }; | ||
| 1021 | - } | ||
| 1022 | - if (parentURL && StringPrototypeStartsWith(parentURL, 'data:')) { | ||
| 1023 | - // This is gonna blow up, we want the error | ||
| 1024 | - new URL(specifier, parentURL); | ||
| 1025 | - } | ||
| 1026 | 1020 | ||
| 1027 | 1021 | const isMain = parentURL === undefined; | |
| 1028 | 1022 | if (isMain) { | |
@@ -1041,7 +1035,8 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 1041 | 1035 | conditions = getConditionsSet(conditions); | |
| 1042 | 1036 | let url; | |
| 1043 | 1037 | try { | |
| 1044 | - url = moduleResolve(specifier, parentURL, conditions); | ||
| 1038 | + url = moduleResolve(specifier, parentURL, conditions, | ||
| 1039 | + isMain ? preserveSymlinksMain : preserveSymlinks); | ||
| 1045 | 1040 | } catch (error) { | |
| 1046 | 1041 | // Try to give the user a hint of what would have been the | |
| 1047 | 1042 | // resolved CommonJS module | |
@@ -1065,17 +1060,9 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 1065 | 1060 | throw error; | |
| 1066 | 1061 | } | |
| 1067 | 1062 | ||
| 1068 | - if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { | ||
| 1069 | - const urlPath = fileURLToPath(url); | ||
| 1070 | - const real = realpathSync(urlPath, { | ||
| 1071 | - [internalFS.realpathCacheKey]: realpathCache | ||
| 1072 | - }); | ||
| 1073 | - const old = url; | ||
| 1074 | - url = pathToFileURL( | ||
| 1075 | - real + (StringPrototypeEndsWith(urlPath, sep) ? '/' : '')); | ||
| 1076 | - url.search = old.search; | ||
| 1077 | - url.hash = old.hash; | ||
| 1078 | - } | ||
| 1063 | + if (url.protocol !== 'file:' && url.protocol !== 'data:' && | ||
| 1064 | + url.protocol !== 'node:') | ||
| 1065 | + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(url); | ||
| 1079 | 1066 | ||
| 1080 | 1067 | return { url: `${url}` }; | |
| 1081 | 1068 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,6 +116,10 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; | |||
| 116 | 116 | // Even though 'pkgexports/sub/asdf.js' works, alternate "path-like" | |
| 117 | 117 | // variants do not to prevent confusion and accidental loopholes. | |
| 118 | 118 | ['pkgexports/sub/./../asdf.js', './sub/./../asdf.js'], | |
| 119 | + // Cannot reach into node_modules, even percent encoded | ||
| 120 | + ['pkgexports/sub/no%64e_modules', './sub/no%64e_modules'], | ||
| 121 | + // Cannot backtrack below exposed path, even with percent encoded "." | ||
| 122 | + ['pkgexports/sub/%2e./asdf', './asdf'], | ||
| 119 | 123 | ]); | |
| 120 | 124 | ||
| 121 | 125 | for (const [specifier, subpath] of undefinedExports) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments