Convert remote path to local encoding

* src/url.c (url_file_name): Convert remote path to local encoding
This commit is contained in:
YX Hao 2017-11-15 19:57:08 +01:00 committed by Tim Rühsen
parent 267cd51fff
commit a9a953feee

View File

@ -1708,35 +1708,43 @@ url_file_name (const struct url *u, char *replaced_filename)
/* If "dirstruct" is turned on (typically the case with -r), add /* If "dirstruct" is turned on (typically the case with -r), add
the host and port (unless those have been turned off) and the host and port (unless those have been turned off) and
directory structure. */ directory structure. */
/* All safe remote chars are unescaped and stored in temp_fnres,
then converted to local and appended to fnres.
Internationalized URL/IDN will produce punycode to lookup IP from DNS:
https://en.wikipedia.org/wiki/URL
https://en.wikipedia.org/wiki/Internationalized_domain_name
Non-ASCII code chars in the path:
https://en.wikipedia.org/wiki/List_of_Unicode_characters
https://en.wikipedia.org/wiki/List_of_writing_systems */
if (opt.dirstruct) if (opt.dirstruct)
{ {
if (opt.protocol_directories) if (opt.protocol_directories)
{ {
if (fnres.tail) if (temp_fnres.tail)
append_char ('/', &fnres); append_char ('/', &temp_fnres);
append_string (supported_schemes[u->scheme].name, &fnres); append_string (supported_schemes[u->scheme].name, &temp_fnres);
} }
if (opt.add_hostdir) if (opt.add_hostdir)
{ {
if (fnres.tail) if (temp_fnres.tail)
append_char ('/', &fnres); append_char ('/', &temp_fnres);
if (0 != strcmp (u->host, "..")) if (0 != strcmp (u->host, ".."))
append_string (u->host, &fnres); append_string (u->host, &temp_fnres);
else else
/* Host name can come from the network; malicious DNS may /* Host name can come from the network; malicious DNS may
allow ".." to be resolved, causing us to write to allow ".." to be resolved, causing us to write to
"../<file>". Defang such host names. */ "../<file>". Defang such host names. */
append_string ("%2E%2E", &fnres); append_string ("%2E%2E", &temp_fnres);
if (u->port != scheme_default_port (u->scheme)) if (u->port != scheme_default_port (u->scheme))
{ {
char portstr[24]; char portstr[24];
number_to_string (portstr, u->port); number_to_string (portstr, u->port);
append_char (FN_PORT_SEP, &fnres); append_char (FN_PORT_SEP, &temp_fnres);
append_string (portstr, &fnres); append_string (portstr, &temp_fnres);
} }
} }
append_dir_structure (u, &fnres); append_dir_structure (u, &temp_fnres);
} }
if (!replaced_filename) if (!replaced_filename)
@ -1750,9 +1758,6 @@ url_file_name (const struct url *u, char *replaced_filename)
fname_len_check = concat_strings (u_file, FN_QUERY_SEP_STR, u->query, NULL); fname_len_check = concat_strings (u_file, FN_QUERY_SEP_STR, u->query, NULL);
else else
fname_len_check = strdupdelim (u_file, u_file + strlen (u_file)); fname_len_check = strdupdelim (u_file, u_file + strlen (u_file));
/* convert before concat with local path */
fname_len_check = convert_fname (fname_len_check);
} }
else else
{ {
@ -1760,12 +1765,23 @@ url_file_name (const struct url *u, char *replaced_filename)
fname_len_check = strdupdelim (u_file, u_file + strlen (u_file)); fname_len_check = strdupdelim (u_file, u_file + strlen (u_file));
} }
if (temp_fnres.tail)
append_char ('/', &temp_fnres);
append_uri_pathel (fname_len_check, append_uri_pathel (fname_len_check,
fname_len_check + strlen (fname_len_check), false, &temp_fnres); fname_len_check + strlen (fname_len_check), true, &temp_fnres);
/* Zero-terminate the temporary file name. */ /* Zero-terminate the temporary file name. */
append_char ('\0', &temp_fnres); append_char ('\0', &temp_fnres);
/* convert all remote chars before length check and appending to local path */
fname = convert_fname (temp_fnres.base);
temp_fnres.base = NULL;
temp_fnres.size = 0;
temp_fnres.tail = 0;
append_string (fname, &temp_fnres);
xfree (fname);
/* Check that the length of the file name is acceptable. */ /* Check that the length of the file name is acceptable. */
#ifdef WINDOWS #ifdef WINDOWS
if (MAX_PATH > (fnres.tail + CHOMP_BUFFER + 2)) if (MAX_PATH > (fnres.tail + CHOMP_BUFFER + 2))