2929# Stop on errors and on usage of unset variables.
3030set -eu
3131
32- VERSION=" 2025.11.04 "
32+ VERSION=" 2026.01.05 "
3333
3434PROGRAM_NAME=" $( basename " $0 " ) "
3535readonly PROGRAM_NAME
@@ -64,10 +64,10 @@ Options:
6464 number appended to the end (curl >= 7.83.0). If this option is provided
6565 multiple times, only the last value is considered.
6666
67- --no-decode-filename: Don't percent-decode the output filename, even if the percent-encoding in
67+ --no-decode-filename: Do not percent-decode the output filename, even if the percent-encoding in
6868 the URL was done by wcurl, e.g.: The URL contained whitespace.
6969
70- --dry-run: Don't actually execute curl, just print what would be invoked.
70+ --dry-run: Do not actually execute curl, just print what would be invoked.
7171
7272 -V, --version: Print version information.
7373
8585# Display an error message and bail out.
8686error ()
8787{
88- printf " %s\n" " $* " > /dev/stderr
88+ printf " %s\n" " $* " >&2
8989 exit 1
9090}
9191
@@ -118,7 +118,8 @@ readonly PER_URL_PARAMETERS="\
118118# characters.
119119# 2F = /
120120# 5C = \
121- readonly UNSAFE_PERCENT_ENCODE=" 2F 5C"
121+ # 3A = :
122+ readonly UNSAFE_PERCENT_ENCODE=" %2F %5C %3A"
122123
123124# Whether to invoke curl or not.
124125DRY_RUN=" false"
@@ -167,7 +168,7 @@ percent_decode()
167168 # If character is a "%", read the next character as decode_hex1.
168169 if [ " ${decode_out} " = % ] && IFS= read -r decode_hex1; then
169170 decode_out=" ${decode_out}${decode_hex1} "
170- # If there's one more character, read it as decode_hex2.
171+ # If there is one more character, read it as decode_hex2.
171172 if IFS= read -r decode_hex2; then
172173 decode_out=" ${decode_out}${decode_hex2} "
173174 # Skip decoding if this is a control character (00-1F).
@@ -190,10 +191,11 @@ get_url_filename()
190191{
191192 # Remove protocol and query string if present.
192193 hostname_and_path=" $( printf %s " ${1} " | sed -e ' s,^[^/]*//,,' -e ' s,?.*$,,' ) "
193- # If what remains contains a slash, there's a path; return it percent-decoded.
194+ # If what remains contains a slash, there is a path; return it percent-decoded.
194195 case " ${hostname_and_path} " in
195196 # sed to remove everything preceding the last '/', e.g.: "example/something" becomes "something"
196- * /* ) percent_decode " $( printf %s " ${hostname_and_path} " | sed -e ' s,^.*/,,' ) " ;;
197+ # sed to also replace ':' with the percent_encoded %3A
198+ * /* ) percent_decode " $( printf %s " ${hostname_and_path} " | sed -e ' s,^.*/,,' -e ' s,:,%3A,g' ) " ;;
197199 esac
198200 # No slash means there was just a hostname and no path; return empty string.
199201}
@@ -210,37 +212,39 @@ exec_curl()
210212
211213 CURL_NO_CLOBBER=" "
212214 CURL_PARALLEL=" "
213- # --no-clobber is only supported since 7.83.0.
214- # --parallel is only supported since 7.66.0.
215- # --parallel-max-host is only supported since 8.16.0.
215+
216216 if [ " ${curl_version_major} " -ge 8 ]; then
217217 CURL_NO_CLOBBER=" --no-clobber"
218- CURL_PARALLEL=" --parallel"
219- if [ " ${curl_version_minor} " -ge 16 ]; then
220- CURL_PARALLEL=" --parallel --parallel-max-host 5"
218+ CURL_PARALLEL=" --parallel --parallel-max-host 5"
219+
220+ # --parallel-max-host is only supported since 8.16.0.
221+ if [ " ${curl_version_major} " -eq 8 ] && [ " ${curl_version_minor} " -lt 16 ]; then
222+ CURL_PARALLEL=" --parallel"
221223 fi
222224 elif [ " ${curl_version_major} " -eq 7 ]; then
225+ # --no-clobber is only supported since 7.83.0.
223226 if [ " ${curl_version_minor} " -ge 83 ]; then
224227 CURL_NO_CLOBBER=" --no-clobber"
225228 fi
229+ # --parallel is only supported since 7.66.0.
226230 if [ " ${curl_version_minor} " -ge 66 ]; then
227231 CURL_PARALLEL=" --parallel"
228232 fi
229233 fi
230234
231- # Detecting whether we need --parallel. It's easier to rely on
235+ # Detecting whether we need --parallel. It is easier to rely on
232236 # the shell's argument parsing.
233237 # shellcheck disable=SC2086
234238 set -- $URLS
235239
236- # If there are less than two URLs, don't set the parallel flag.
240+ # If there are less than two URLs, do not set the parallel flag.
237241 if [ " $# " -lt 2 ]; then
238242 CURL_PARALLEL=" "
239243 fi
240244
241245 # Start assembling the command.
242246 #
243- # We use 'set --' here (again) because (a) we don't have arrays on
247+ # We use 'set --' here (again) because (a) we do not have arrays on
244248 # POSIX shell, and (b) we need better control over the way we
245249 # split arguments.
246250 #
0 commit comments