@@ -130,9 +130,10 @@ const { validateString } = require('internal/validators');
130
130
const pendingDeprecation = getOptionValue ( '--pending-deprecation' ) ;
131
131
132
132
const {
133
- CHAR_FORWARD_SLASH ,
134
133
CHAR_BACKWARD_SLASH ,
135
- CHAR_COLON
134
+ CHAR_COLON ,
135
+ CHAR_DOT ,
136
+ CHAR_FORWARD_SLASH ,
136
137
} = require ( 'internal/constants' ) ;
137
138
138
139
const {
@@ -538,7 +539,12 @@ function resolveExports(nmPath, request) {
538
539
}
539
540
}
540
541
541
- const trailingSlashRegex = / (?: ^ | \/ ) \. ? \. $ / ;
542
+ /**
543
+ * @param {string } request a relative or absolute file path
544
+ * @param {Array<string> } paths file system directories to search as file paths
545
+ * @param {boolean } isMain if the request is the main app entry point
546
+ * @returns {string | false }
547
+ */
542
548
Module . _findPath = function ( request , paths , isMain ) {
543
549
const absoluteRequest = path . isAbsolute ( request ) ;
544
550
if ( absoluteRequest ) {
@@ -553,18 +559,42 @@ Module._findPath = function(request, paths, isMain) {
553
559
return entry ;
554
560
555
561
let exts ;
556
- let trailingSlash = request . length > 0 &&
557
- StringPrototypeCharCodeAt ( request , request . length - 1 ) ===
558
- CHAR_FORWARD_SLASH ;
559
- if ( ! trailingSlash ) {
560
- trailingSlash = RegExpPrototypeExec ( trailingSlashRegex , request ) !== null ;
562
+ const trailingSlash = request . length > 0 &&
563
+ ( StringPrototypeCharCodeAt ( request , request . length - 1 ) === CHAR_FORWARD_SLASH || (
564
+ StringPrototypeCharCodeAt ( request , request . length - 1 ) === CHAR_DOT &&
565
+ (
566
+ request . length === 1 ||
567
+ StringPrototypeCharCodeAt ( request , request . length - 2 ) === CHAR_FORWARD_SLASH ||
568
+ ( StringPrototypeCharCodeAt ( request , request . length - 2 ) === CHAR_DOT && (
569
+ request . length === 2 ||
570
+ StringPrototypeCharCodeAt ( request , request . length - 3 ) === CHAR_FORWARD_SLASH
571
+ ) )
572
+ )
573
+ ) ) ;
574
+
575
+ const isRelative = StringPrototypeCharCodeAt ( request , 0 ) === CHAR_DOT &&
576
+ (
577
+ request . length === 1 ||
578
+ StringPrototypeCharCodeAt ( request , 1 ) === CHAR_FORWARD_SLASH ||
579
+ ( isWindows && StringPrototypeCharCodeAt ( request , 1 ) === CHAR_BACKWARD_SLASH ) ||
580
+ ( StringPrototypeCharCodeAt ( request , 1 ) === CHAR_DOT && ( (
581
+ request . length === 2 ||
582
+ StringPrototypeCharCodeAt ( request , 2 ) === CHAR_FORWARD_SLASH ) ||
583
+ ( isWindows && StringPrototypeCharCodeAt ( request , 2 ) === CHAR_BACKWARD_SLASH ) ) )
584
+ ) ;
585
+ let insidePath = true ;
586
+ if ( isRelative ) {
587
+ const normalizedRequest = path . normalize ( request ) ;
588
+ if ( StringPrototypeStartsWith ( normalizedRequest , '..' ) ) {
589
+ insidePath = false ;
590
+ }
561
591
}
562
592
563
593
// For each path
564
594
for ( let i = 0 ; i < paths . length ; i ++ ) {
565
- // Don't search further if path doesn't exist
595
+ // Don't search further if path doesn't exist and request is inside the path
566
596
const curPath = paths [ i ] ;
567
- if ( curPath && _stat ( curPath ) < 1 ) continue ;
597
+ if ( insidePath && curPath && _stat ( curPath ) < 1 ) continue ;
568
598
569
599
if ( ! absoluteRequest ) {
570
600
const exportsResolved = resolveExports ( curPath , request ) ;
0 commit comments