Ignore multiple trailing '/' in path elements (#690)

Multiple unescaped trailing path separators should be trimmed from input elements so there are no empty elements or trailing unescaped separators at the end of the path or between elements
This commit is contained in:
ashmrtn 2022-08-30 12:30:28 -07:00 committed by GitHub
parent 0b7fe0fdb9
commit ee57c7cb6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 16 deletions

View File

@ -245,31 +245,30 @@ func validateEscapedElement(element string) error {
} }
// trimTrailingSlash takes an escaped path element and returns an escaped path // trimTrailingSlash takes an escaped path element and returns an escaped path
// element with the trailing path separator character removed if it was not // element with the trailing path separator character(s) removed if they were not
// escaped. If there was no trailing path separator character or the separator // escaped. If there were no trailing path separator character(s) or the separator(s)
// was escaped the input is returned unchanged. // were escaped the input is returned unchanged.
func trimTrailingSlash(element string) string { func trimTrailingSlash(element string) string {
lastIdx := len(element) - 1 for len(element) > 0 && element[len(element)-1] == pathSeparator {
lastIdx := len(element) - 1
numSlashes := 0
if element[lastIdx] != pathSeparator { for i := lastIdx - 1; i >= 0; i-- {
return element if element[i] != escapeCharacter {
} break
}
numSlashes := 0 numSlashes++
}
for i := lastIdx - 1; i >= 0; i-- { if numSlashes%2 != 0 {
if element[i] != escapeCharacter {
break break
} }
numSlashes++ element = element[:lastIdx]
} }
if numSlashes%2 != 0 { return element
return element
}
return element[:lastIdx]
} }
// join returns a string containing the given elements joined by the path // join returns a string containing the given elements joined by the path

View File

@ -169,6 +169,16 @@ var basicEscapedInputs = []testData{
}, },
expectedString: `this/is/a/path`, expectedString: `this/is/a/path`,
}, },
{
name: "MultipleTrailingElementSeparator",
input: []string{
`this`,
`is`,
`a///`,
`path`,
},
expectedString: `this/is/a/path`,
},
{ {
name: "TrailingSeparatorAtEnd", name: "TrailingSeparatorAtEnd",
input: []string{ input: []string{
@ -179,6 +189,16 @@ var basicEscapedInputs = []testData{
}, },
expectedString: `this/is/a/path`, expectedString: `this/is/a/path`,
}, },
{
name: "MultipleTrailingSeparatorAtEnd",
input: []string{
`this`,
`is`,
`a`,
`path///`,
},
expectedString: `this/is/a/path`,
},
{ {
name: "TrailingSeparatorWithEmptyElementAtEnd", name: "TrailingSeparatorWithEmptyElementAtEnd",
input: []string{ input: []string{