@@ -470,28 +470,73 @@ func simpleNormalizePath(path string) (string, bool) {
470470 return "" , false
471471}
472472
473+ // hasRelativePathSegment reports whether p contains ".", "..", "./", "../", "/.", "/..", "//", "/./", or "/../".
473474func hasRelativePathSegment (p string ) bool {
474- if p == "." || p == ".." {
475- return true
475+ n := len (p )
476+ if n == 0 {
477+ return false
476478 }
477479
478- if strings . HasPrefix ( p , "./" ) || strings . HasPrefix ( p , "../" ) {
480+ if p == "." || p == ".." {
479481 return true
480482 }
481483
482- if strings .HasSuffix (p , "/." ) || strings .HasSuffix (p , "/.." ) {
483- return true
484+ // Leading "./" OR "../"
485+ if p [0 ] == '.' {
486+ if n >= 2 && p [1 ] == '/' {
487+ return true
488+ }
489+ // Leading "../"
490+ if n >= 3 && p [1 ] == '.' && p [2 ] == '/' {
491+ return true
492+ }
484493 }
485-
486- if strings .Contains (p , "//" ) {
487- return true
494+ // Trailing "/." OR "/.."
495+ if p [n - 1 ] == '.' {
496+ if n >= 2 && p [n - 2 ] == '/' {
497+ return true
498+ }
499+ if n >= 3 && p [n - 2 ] == '.' && p [n - 3 ] == '/' {
500+ return true
501+ }
488502 }
489503
490- if strings .Contains (p , "/./" ) || strings .Contains (p , "/../" ) {
491- return true
504+ // Now look for any `//` or `/./` or `/../`
505+
506+ prevSlash := false
507+ segLen := 0 // length of current segment since last slash
508+ dotCount := 0 // consecutive dots at start of the current segment; -1 => not only dots
509+
510+ for i := range n {
511+ c := p [i ]
512+ if c == '/' {
513+ // "//"
514+ if prevSlash {
515+ return true
516+ }
517+ // "/./" or "/../"
518+ if (segLen == 1 && dotCount == 1 ) || (segLen == 2 && dotCount == 2 ) {
519+ return true
520+ }
521+ prevSlash = true
522+ segLen = 0
523+ dotCount = 0
524+ continue
525+ }
526+
527+ if c == '.' {
528+ if dotCount >= 0 {
529+ dotCount ++
530+ }
531+ } else {
532+ dotCount = - 1
533+ }
534+ segLen ++
535+ prevSlash = false
492536 }
493537
494- return false
538+ // Trailing "/." or "/.."
539+ return (segLen == 1 && dotCount == 1 ) || (segLen == 2 && dotCount == 2 )
495540}
496541
497542func NormalizePath (path string ) string {
0 commit comments