Skip to content

Commit 524f7e7

Browse files
samuelophSergio Durigan Junior
andcommitted
Don't percent-decode '/' and '\' in output file name
Co-Authored-by: Sergio Durigan Junior <[email protected]>
1 parent 3e454d9 commit 524f7e7

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

tests/tests.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ testUrlDecodingWhitespaceTrailingSlash()
200200
assertContains "Verify whether 'wcurl' successfully uses the default filename when the URL ends with a slash" "${ret}" 'index.html'
201201
}
202202

203+
testUrlDecodingBackslashes()
204+
{
205+
url='example.com/filename%5Cwith%2Fbackslashes%5c%2f'
206+
ret=$(${WCURL_CMD} ${url} 2>&1)
207+
assertContains "Verify whether 'wcurl' successfully uses the default filename when the URL ends with a slash" "${ret}" 'filename%5Cwith%2Fbackslashes%5c%2f'
208+
}
209+
203210
# Test decoding a bunch of different languages (that don't use the latin
204211
# alphabet), we could split each language on its own test, but for now it
205212
# doesn't make a difference.

wcurl

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ readonly PER_URL_PARAMETERS="\
113113
--remote-time \
114114
--retry 5 "
115115

116+
# Valid percent-encode codes that are considered unsafe to be decoded.
117+
# This is a list of space-separated percent-encoded uppercase
118+
# characters.
119+
# 2F = /
120+
# 5C = \
121+
readonly UNSAFE_PERCENT_ENCODE="2F 5C"
122+
116123
# Whether to invoke curl or not.
117124
DRY_RUN="false"
118125

@@ -137,6 +144,20 @@ is_subset_of()
137144
esac
138145
}
139146

147+
# Indicate via exit code whether the HTML code given in the first
148+
# parameter is safe to be decoded.
149+
is_safe_percent_encode()
150+
{
151+
upper_str=$(printf "%s" "${1}" | tr "[:lower:]" "[:upper:]")
152+
for unsafe in ${UNSAFE_PERCENT_ENCODE}; do
153+
if [ "${unsafe}" = "${upper_str}" ]; then
154+
return 1
155+
fi
156+
done
157+
158+
return 0
159+
}
160+
140161
# Print the given string percent-decoded.
141162
percent_decode()
142163
{
@@ -151,9 +172,10 @@ percent_decode()
151172
decode_out="${decode_out}${decode_hex2}"
152173
# Skip decoding if this is a control character (00-1F).
153174
# Skip decoding if DECODE_FILENAME is not "true".
154-
if is_subset_of "${decode_hex1}" "23456789abcdefABCDEF" \
175+
if [ "${DECODE_FILENAME}" = "true" ] \
176+
&& is_subset_of "${decode_hex1}" "23456789abcdefABCDEF" \
155177
&& is_subset_of "${decode_hex2}" "0123456789abcdefABCDEF" \
156-
&& [ "${DECODE_FILENAME}" = "true" ]; then
178+
&& is_safe_percent_encode "${decode_out}"; then
157179
# Use printf to decode it into octal and then decode it to the final format.
158180
decode_out="$(printf "%b" "\\$(printf %o "0x${decode_hex1}${decode_hex2}")")"
159181
fi

0 commit comments

Comments
 (0)