| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1076,59 +1076,63 @@ The resolver can throw the following errors: | |||
| 1076 | 1076 | > 1. Note: _specifier_ is now a bare specifier. | |
| 1077 | 1077 | > 2. Set _resolved_ the result of | |
| 1078 | 1078 | > **PACKAGE\_RESOLVE**(_specifier_, _parentURL_). | |
| 1079 | - > 6. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2f"_ | ||
| 1080 | - > and _"%5C"_ respectively), then | ||
| 1081 | - > 1. Throw an _Invalid Module Specifier_ error. | ||
| 1082 | - > 7. If the file at _resolved_ is a directory, then | ||
| 1083 | - > 1. Throw an _Unsupported Directory Import_ error. | ||
| 1084 | - > 8. If the file at _resolved_ does not exist, then | ||
| 1085 | - > 1. Throw a _Module Not Found_ error. | ||
| 1086 | - > 9. Set _resolved_ to the real path of _resolved_. | ||
| 1087 | - > 10. Let _format_ be the result of **ESM\_FORMAT**(_resolved_). | ||
| 1088 | - > 11. Load _resolved_ as module format, _format_. | ||
| 1089 | - > 12. Return _resolved_. | ||
| 1079 | + > 6. Let _format_ be **undefined**. | ||
| 1080 | + > 7. If _resolved_ is a _"file:"_ URL, then | ||
| 1081 | + > 1. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2F"_ | ||
| 1082 | + > and _"%5C"_ respectively), then | ||
| 1083 | + > 1. Throw an _Invalid Module Specifier_ error. | ||
| 1084 | + > 2. If the file at _resolved_ is a directory, then | ||
| 1085 | + > 1. Throw an _Unsupported Directory Import_ error. | ||
| 1086 | + > 3. If the file at _resolved_ does not exist, then | ||
| 1087 | + > 1. Throw a _Module Not Found_ error. | ||
| 1088 | + > 4. Set _resolved_ to the real path of _resolved_, maintaining the | ||
| 1089 | + > same URL querystring and fragment components. | ||
| 1090 | + > 5. Set _format_ to the result of **ESM\_FILE\_FORMAT**(_resolved_). | ||
| 1091 | + > 8. Otherwise, | ||
| 1092 | + > 1. Set _format_ the module format of the content type associated with the | ||
| 1093 | + > URL _resolved_. | ||
| 1094 | + > 9. Load _resolved_ as module format, _format_. | ||
| 1090 | 1095 | ||
| 1091 | 1096 | **PACKAGE\_RESOLVE**(_packageSpecifier_, _parentURL_) | |
| 1092 | 1097 | ||
| 1093 | 1098 | > 1. Let _packageName_ be **undefined**. | |
| 1094 | 1099 | > 2. If _packageSpecifier_ is an empty string, then | |
| 1095 | 1100 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1096 | - > 3. If _packageSpecifier_ does not start with _"@"_, then | ||
| 1101 | + > 3. If _packageSpecifier_ is a Node.js builtin module name, then | ||
| 1102 | + > 1. Return the string _"node:"_ concatenated with _packageSpecifier_. | ||
| 1103 | + > 4. If _packageSpecifier_ does not start with _"@"_, then | ||
| 1097 | 1104 | > 1. Set _packageName_ to the substring of _packageSpecifier_ until the first | |
| 1098 | 1105 | > _"/"_ separator or the end of the string. | |
| 1099 | - > 4. Otherwise, | ||
| 1106 | + > 5. Otherwise, | ||
| 1100 | 1107 | > 1. If _packageSpecifier_ does not contain a _"/"_ separator, then | |
| 1101 | 1108 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1102 | 1109 | > 2. Set _packageName_ to the substring of _packageSpecifier_ | |
| 1103 | 1110 | > until the second _"/"_ separator or the end of the string. | |
| 1104 | - > 5. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then | ||
| 1111 | + > 6. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then | ||
| 1105 | 1112 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1106 | - > 6. Let _packageSubpath_ be _"."_ concatenated with the substring of | ||
| 1113 | + > 7. Let _packageSubpath_ be _"."_ concatenated with the substring of | ||
| 1107 | 1114 | > _packageSpecifier_ from the position at the length of _packageName_. | |
| 1108 | - > 7. If _packageSubpath_ ends in _"/"_, then | ||
| 1115 | + > 8. If _packageSubpath_ ends in _"/"_, then | ||
| 1109 | 1116 | > 1. Throw an _Invalid Module Specifier_ error. | |
| 1110 | - > 8. Let _selfUrl_ be the result of | ||
| 1117 | + > 9. Let _selfUrl_ be the result of | ||
| 1111 | 1118 | > **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_). | |
| 1112 | - > 9. If _selfUrl_ is not **undefined**, return _selfUrl_. | ||
| 1113 | - > 10. If _packageSubpath_ is _"."_ and _packageName_ is a Node.js builtin | ||
| 1114 | - > module, then | ||
| 1115 | - > 1. Return the string _"node:"_ concatenated with _packageSpecifier_. | ||
| 1119 | + > 10. If _selfUrl_ is not **undefined**, return _selfUrl_. | ||
| 1116 | 1120 | > 11. While _parentURL_ is not the file system root, | |
| 1117 | - > 1. Let _packageURL_ be the URL resolution of _"node\_modules/"_ | ||
| 1118 | - > concatenated with _packageSpecifier_, relative to _parentURL_. | ||
| 1119 | - > 2. Set _parentURL_ to the parent folder URL of _parentURL_. | ||
| 1120 | - > 3. If the folder at _packageURL_ does not exist, then | ||
| 1121 | - > 1. Continue the next loop iteration. | ||
| 1122 | - > 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). | ||
| 1123 | - > 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or | ||
| 1124 | - > **undefined**, then | ||
| 1125 | - > 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, | ||
| 1126 | - > _packageSubpath_, _pjson.exports_, _defaultConditions_). | ||
| 1127 | - > 6. Otherwise, if _packageSubpath_ is equal to _"."_, then | ||
| 1128 | - > 1. If _pjson.main_ is a string, then | ||
| 1129 | - > 1. Return the URL resolution of _main_ in _packageURL_. | ||
| 1130 | - > 7. Otherwise, | ||
| 1131 | - > 1. Return the URL resolution of _packageSubpath_ in _packageURL_. | ||
| 1121 | + > 1. Let _packageURL_ be the URL resolution of _"node_modules/"_ | ||
| 1122 | + > concatenated with _packageSpecifier_, relative to _parentURL_. | ||
| 1123 | + > 2. Set _parentURL_ to the parent folder URL of _parentURL_. | ||
| 1124 | + > 3. If the folder at _packageURL_ does not exist, then | ||
| 1125 | + > 1. Continue the next loop iteration. | ||
| 1126 | + > 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). | ||
| 1127 | + > 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or | ||
| 1128 | + > **undefined**, then | ||
| 1129 | + > 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, | ||
| 1130 | + > _packageSubpath_, _pjson.exports_, _defaultConditions_). | ||
| 1131 | + > 6. Otherwise, if _packageSubpath_ is equal to _"."_, then | ||
| 1132 | + > 1. If _pjson.main_ is a string, then | ||
| 1133 | + > 1. Return the URL resolution of _main_ in _packageURL_. | ||
| 1134 | + > 7. Otherwise, | ||
| 1135 | + > 1. Return the URL resolution of _packageSubpath_ in _packageURL_. | ||
| 1132 | 1136 | > 12. Throw a _Module Not Found_ error. | |
| 1133 | 1137 | ||
| 1134 | 1138 | **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_) | |
@@ -1238,18 +1242,20 @@ _internal_, _conditions_) | |||
| 1238 | 1242 | > _"/"_ and is not a valid URL, then | |
| 1239 | 1243 | > 1. If _pattern_ is **true**, then | |
| 1240 | 1244 | > 1. Return **PACKAGE\_RESOLVE**(_target_ with every instance of | |
| 1241 | - > _"\*"_ replaced by _subpath_, _packageURL_ + _"/"_)\_. | ||
| 1245 | + > _"\*"_ replaced by _subpath_, _packageURL_ + _"/"_). | ||
| 1242 | 1246 | > 2. Return **PACKAGE\_RESOLVE**(_target_ + _subpath_, | |
| 1243 | - > _packageURL_ + _"/"_)\_. | ||
| 1247 | + > _packageURL_ + _"/"_)_. | ||
| 1244 | 1248 | > 2. Otherwise, throw an _Invalid Package Target_ error. | |
| 1245 | 1249 | > 3. If _target_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or | |
| 1246 | - > _"node\_modules"_ segments after the first segment, throw an | ||
| 1247 | - > _Invalid Package Target_ error. | ||
| 1250 | + > _"node\_modules"_ segments after the first segment, case insensitive and | ||
| 1251 | + > including percent encoded variants, throw an _Invalid Package Target_ | ||
| 1252 | + > error. | ||
| 1248 | 1253 | > 4. Let _resolvedTarget_ be the URL resolution of the concatenation of | |
| 1249 | 1254 | > _packageURL_ and _target_. | |
| 1250 | 1255 | > 5. Assert: _resolvedTarget_ is contained in _packageURL_. | |
| 1251 | 1256 | > 6. If _subpath_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or | |
| 1252 | - > _"node\_modules"_ segments, throw an _Invalid Module Specifier_ error. | ||
| 1257 | + > _"node\_modules"_ segments, case insensitive and including percent | ||
| 1258 | + > encoded variants, throw an _Invalid Module Specifier_ error. | ||
| 1253 | 1259 | > 7. If _pattern_ is **true**, then | |
| 1254 | 1260 | > 1. Return the URL resolution of _resolvedTarget_ with every instance of | |
| 1255 | 1261 | > _"\*"_ replaced with _subpath_. | |
@@ -1282,19 +1288,21 @@ _internal_, _conditions_) | |||
| 1282 | 1288 | > 4. Otherwise, if _target_ is _null_, return **null**. | |
| 1283 | 1289 | > 5. Otherwise throw an _Invalid Package Target_ error. | |
| 1284 | 1290 | ||
| 1285 | - **ESM\_FORMAT**(_url_) | ||
| 1291 | + **ESM\_FILE\_FORMAT**(_url_) | ||
| 1286 | 1292 | ||
| 1287 | 1293 | > 1. Assert: _url_ corresponds to an existing file. | |
| 1288 | 1294 | > 2. Let _pjson_ be the result of **READ\_PACKAGE\_SCOPE**(_url_). | |
| 1289 | 1295 | > 3. If _url_ ends in _".mjs"_, then | |
| 1290 | 1296 | > 1. Return _"module"_. | |
| 1291 | 1297 | > 4. If _url_ ends in _".cjs"_, then | |
| 1292 | 1298 | > 1. Return _"commonjs"_. | |
| 1293 | - > 5. If _pjson?.type_ exists and is _"module"_, then | ||
| 1299 | + > 5. If _url_ ends in _".json"_, then | ||
| 1300 | + > 1. Return _"json"_. | ||
| 1301 | + > 6. If _pjson?.type_ exists and is _"module"_, then | ||
| 1294 | 1302 | > 1. If _url_ ends in _".js"_, then | |
| 1295 | 1303 | > 1. Return _"module"_. | |
| 1296 | 1304 | > 2. Throw an _Unsupported File Extension_ error. | |
| 1297 | - > 6. Otherwise, | ||
| 1305 | + > 7. Otherwise, | ||
| 1298 | 1306 | > 1. Throw an _Unsupported File Extension_ error. | |
| 1299 | 1307 | ||
| 1300 | 1308 | **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, | |
@@ -360,9 +361,10 @@ const encodedSepRegEx = /%2F|%5C/i; | |||
| 360 | 361 | /** | |
| 361 | 362 | * @param {URL} resolved | |
| 362 | 363 | * @param {string | URL | undefined} base | |
| 364 | + * @param {boolean} preserveSymlinks | ||
| 363 | 365 | * @returns {URL | undefined} | |
| 364 | 366 | */ | |
| 365 | - function finalizeResolution(resolved, base) { | ||
| 367 | + function finalizeResolution(resolved, base, preserveSymlinks) { | ||
| 366 | 368 | if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) | |
| 367 | 369 | throw new ERR_INVALID_MODULE_SPECIFIER( | |
| 368 | 370 | resolved.pathname, 'must not include encoded "/" or "\\" characters', | |
@@ -393,6 +395,17 @@ function finalizeResolution(resolved, base) { | |||
| 393 | 395 | path || resolved.pathname, base && fileURLToPath(base), 'module'); | |
| 394 | 396 | } | |
| 395 | 397 | ||
| 398 | + if (!preserveSymlinks) { | ||
| 399 | + const real = realpathSync(path, { | ||
| 400 | + [internalFS.realpathCacheKey]: realpathCache | ||
| 401 | + }); | ||
| 402 | + const { search, hash } = resolved; | ||
| 403 | + resolved = | ||
| 404 | + pathToFileURL(real + (StringPrototypeEndsWith(path, sep) ? '/' : '')); | ||
| 405 | + resolved.search = search; | ||
| 406 | + resolved.hash = hash; | ||
| 407 | + } | ||
| 408 | + | ||
| 396 | 409 | return resolved; | |
| 397 | 410 | } | |
| 398 | 411 | ||
@@ -444,7 +457,8 @@ function throwInvalidPackageTarget( | |||
| 444 | 457 | internal, base && fileURLToPath(base)); | |
| 445 | 458 | } | |
| 446 | 459 | ||
| 447 | - const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; | ||
| 460 | + 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; | ||
| 461 | + const invalidPackageNameRegEx = /^\.|%|\\/; | ||
| 448 | 462 | const patternRegEx = /\*/g; | |
| 449 | 463 | ||
| 450 | 464 | function resolvePackageTargetString( | |
@@ -777,13 +791,9 @@ function parsePackageName(specifier, base) { | |||
| 777 | 791 | specifier : StringPrototypeSlice(specifier, 0, separatorIndex); | |
| 778 | 792 | ||
| 779 | 793 | // Package name cannot have leading . and cannot have percent-encoding or | |
| 780 | - // separators. | ||
| 781 | - for (let i = 0; i < packageName.length; i++) { | ||
| 782 | - if (packageName[i] === '%' || packageName[i] === '\\') { | ||
| 783 | - validPackageName = false; | ||
| 784 | - break; | ||
| 785 | - } | ||
| 786 | - } | ||
| 794 | + // \\ separators. | ||
| 795 | + if (RegExpPrototypeExec(invalidPackageNameRegEx, packageName) !== null) | ||
| 796 | + validPackageName = false; | ||
| 787 | 797 | ||
| 788 | 798 | if (!validPackageName) { | |
| 789 | 799 | throw new ERR_INVALID_MODULE_SPECIFIER( | |
@@ -803,6 +813,9 @@ function parsePackageName(specifier, base) { | |||
| 803 | 813 | * @returns {URL} | |
| 804 | 814 | */ | |
| 805 | 815 | function packageResolve(specifier, base, conditions) { | |
| 816 | + if (NativeModule.canBeRequiredByUsers(specifier)) | ||
| 817 | + return new URL('node:' + specifier); | ||
| 818 | + | ||
| 806 | 819 | const { packageName, packageSubpath, isScoped } = | |
| 807 | 820 | parsePackageName(specifier, base); | |
| 808 | 821 | ||
@@ -879,9 +892,10 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { | |||
| 879 | 892 | * @param {string} specifier | |
| 880 | 893 | * @param {string | URL | undefined} base | |
| 881 | 894 | * @param {Set<string>} conditions | |
| 895 | + * @param {boolean} preserveSymlinks | ||
| 882 | 896 | * @returns {URL} | |
| 883 | 897 | */ | |
| 884 | - function moduleResolve(specifier, base, conditions) { | ||
| 898 | + function moduleResolve(specifier, base, conditions, preserveSymlinks) { | ||
| 885 | 899 | // Order swapped from spec for minor perf gain. | |
| 886 | 900 | // Ok since relative URLs cannot parse as URLs. | |
| 887 | 901 | let resolved; | |
@@ -896,7 +910,9 @@ function moduleResolve(specifier, base, conditions) { | |||
| 896 | 910 | resolved = packageResolve(specifier, base, conditions); | |
| 897 | 911 | } | |
| 898 | 912 | } | |
| 899 | - return finalizeResolution(resolved, base); | ||
| 913 | + if (resolved.protocol !== 'file:') | ||
| 914 | + return resolved; | ||
| 915 | + return finalizeResolution(resolved, base, preserveSymlinks); | ||
| 900 | 916 | } | |
| 901 | 917 | ||
| 902 | 918 | /** | |
@@ -968,28 +984,6 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 968 | 984 | } | |
| 969 | 985 | } | |
| 970 | 986 | } | |
| 971 | - let parsed; | ||
| 972 | - try { | ||
| 973 | - parsed = new URL(specifier); | ||
| 974 | - if (parsed.protocol === 'data:') { | ||
| 975 | - return { | ||
| 976 | - url: specifier | ||
| 977 | - }; | ||
| 978 | - } | ||
| 979 | - } catch {} | ||
| 980 | - if (parsed && parsed.protocol === 'node:') | ||
| 981 | - return { url: specifier }; | ||
| 982 | - if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') | ||
| 983 | - throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed); | ||
| 984 | - if (NativeModule.canBeRequiredByUsers(specifier)) { | ||
| 985 | - return { | ||
| 986 | - url: 'node:' + specifier | ||
| 987 | - }; | ||
| 988 | - } | ||
| 989 | - if (parentURL && StringPrototypeStartsWith(parentURL, 'data:')) { | ||
| 990 | - // This is gonna blow up, we want the error | ||
| 991 | - new URL(specifier, parentURL); | ||
| 992 | - } | ||
| 993 | 987 | ||
| 994 | 988 | const isMain = parentURL === undefined; | |
| 995 | 989 | if (isMain) { | |
@@ -1008,7 +1002,8 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 1008 | 1002 | conditions = getConditionsSet(conditions); | |
| 1009 | 1003 | let url; | |
| 1010 | 1004 | try { | |
| 1011 | - url = moduleResolve(specifier, parentURL, conditions); | ||
| 1005 | + url = moduleResolve(specifier, parentURL, conditions, | ||
| 1006 | + isMain ? preserveSymlinksMain : preserveSymlinks); | ||
| 1012 | 1007 | } catch (error) { | |
| 1013 | 1008 | // Try to give the user a hint of what would have been the | |
| 1014 | 1009 | // resolved CommonJS module | |
@@ -1032,17 +1027,9 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) { | |||
| 1032 | 1027 | throw error; | |
| 1033 | 1028 | } | |
| 1034 | 1029 | ||
| 1035 | - if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { | ||
| 1036 | - const urlPath = fileURLToPath(url); | ||
| 1037 | - const real = realpathSync(urlPath, { | ||
| 1038 | - [internalFS.realpathCacheKey]: realpathCache | ||
| 1039 | - }); | ||
| 1040 | - const old = url; | ||
| 1041 | - url = pathToFileURL( | ||
| 1042 | - real + (StringPrototypeEndsWith(urlPath, sep) ? '/' : '')); | ||
| 1043 | - url.search = old.search; | ||
| 1044 | - url.hash = old.hash; | ||
| 1045 | - } | ||
| 1030 | + if (url.protocol !== 'file:' && url.protocol !== 'data:' && | ||
| 1031 | + url.protocol !== 'node:') | ||
| 1032 | + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(url); | ||
| 1046 | 1033 | ||
| 1047 | 1034 | return { url: `${url}` }; | |
| 1048 | 1035 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,6 +104,10 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; | |||
| 104 | 104 | // Even though 'pkgexports/sub/asdf.js' works, alternate "path-like" | |
| 105 | 105 | // variants do not to prevent confusion and accidental loopholes. | |
| 106 | 106 | ['pkgexports/sub/./../asdf.js', './sub/./../asdf.js'], | |
| 107 | + // Cannot reach into node_modules, even percent encoded | ||
| 108 | + ['pkgexports/sub/no%64e_modules', './sub/no%64e_modules'], | ||
| 109 | + // Cannot backtrack below exposed path, even with percent encoded "." | ||
| 110 | + ['pkgexports/sub/%2e./asdf', './asdf'], | ||
| 107 | 111 | ]); | |
| 108 | 112 | ||
| 109 | 113 | for (const [specifier, subpath] of undefinedExports) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments