X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Furl.c;h=afc31811d443378c7576a5eb17d6e919ba792298;hp=3f4b89920fd2f5d2b37956f3c6f05ba0086051af;hb=d763f8bf6d6e13ce006ffab616cc8a77e747a633;hpb=dc9abe478f8175d342f190993d0dc61891a7da8e diff --git a/src/url.c b/src/url.c index 3f4b8992..afc31811 100644 --- a/src/url.c +++ b/src/url.c @@ -43,6 +43,10 @@ as that of the covered work. */ #include "url.h" #include "host.h" /* for is_valid_ipv6_address */ +#ifdef __VMS +#include "vms.h" +#endif /* def __VMS */ + #ifdef TESTING #include "test.h" #endif @@ -252,6 +256,15 @@ url_escape (const char *s) return url_escape_1 (s, urlchr_unsafe, false); } +/* URL-escape the unsafe and reserved characters (see urlchr_table) in + a given string, returning a freshly allocated string. */ + +char * +url_escape_unsafe_and_reserved (const char *s) +{ + return url_escape_1 (s, urlchr_unsafe|urlchr_reserved, false); +} + /* URL-escape the unsafe characters (see urlchr_table) in a given string. If no characters are unsafe, S is returned. */ @@ -619,18 +632,20 @@ static const char *parse_errors[] = { #define PE_NO_ERROR 0 N_("No error"), #define PE_UNSUPPORTED_SCHEME 1 - N_("Unsupported scheme %s"), -#define PE_INVALID_HOST_NAME 2 + N_("Unsupported scheme %s"), /* support for format token only here */ +#define PE_MISSING_SCHEME 2 + N_("Scheme missing"), +#define PE_INVALID_HOST_NAME 3 N_("Invalid host name"), -#define PE_BAD_PORT_NUMBER 3 +#define PE_BAD_PORT_NUMBER 4 N_("Bad port number"), -#define PE_INVALID_USER_NAME 4 +#define PE_INVALID_USER_NAME 5 N_("Invalid user name"), -#define PE_UNTERMINATED_IPV6_ADDRESS 5 +#define PE_UNTERMINATED_IPV6_ADDRESS 6 N_("Unterminated IPv6 numeric address"), -#define PE_IPV6_NOT_SUPPORTED 6 +#define PE_IPV6_NOT_SUPPORTED 7 N_("IPv6 addresses not supported"), -#define PE_INVALID_IPV6_ADDRESS 7 +#define PE_INVALID_IPV6_ADDRESS 8 N_("Invalid IPv6 numeric address") }; @@ -640,7 +655,7 @@ static const char *parse_errors[] = { error, and if ERROR is not NULL, also set *ERROR to the appropriate error code. */ struct url * -url_parse (const char *url, int *error) +url_parse (const char *url, int *error, struct iri *iri, bool percent_encode) { struct url *u; const char *p; @@ -659,20 +674,41 @@ url_parse (const char *url, int *error) int port; char *user = NULL, *passwd = NULL; - char *url_encoded = NULL; + const char *url_encoded = NULL; + char *new_url = NULL; int error_code; scheme = url_scheme (url); if (scheme == SCHEME_INVALID) { - error_code = PE_UNSUPPORTED_SCHEME; + if (url_has_scheme (url)) + error_code = PE_UNSUPPORTED_SCHEME; + else + error_code = PE_MISSING_SCHEME; goto error; } - url_encoded = reencode_escapes (url); + if (iri && iri->utf8_encode) + { + iri->utf8_encode = remote_to_utf8 (iri, iri->orig_url ? iri->orig_url : url, (const char **) &new_url); + if (!iri->utf8_encode) + new_url = NULL; + else + iri->orig_url = xstrdup (url); + } + + /* XXX XXX Could that change introduce (security) bugs ??? XXX XXX*/ + if (percent_encode) + url_encoded = reencode_escapes (new_url ? new_url : url); + else + url_encoded = new_url ? new_url : url; + p = url_encoded; + if (new_url && url_encoded != new_url) + xfree (new_url); + p += strlen (supported_schemes[scheme].leading_string); uname_b = p; p = url_skip_credentials (p); @@ -842,6 +878,18 @@ url_parse (const char *url, int *error) { url_unescape (u->host); host_modified = true; + + /* Apply IDNA regardless of iri->utf8_encode status */ + if (opt.enable_iri && iri) + { + char *new = idn_encode (iri, u->host); + if (new) + { + xfree (u->host); + u->host = new; + host_modified = true; + } + } } if (params_b) @@ -851,7 +899,7 @@ url_parse (const char *url, int *error) if (fragment_b) u->fragment = strdupdelim (fragment_b, fragment_e); - if (path_modified || u->fragment || host_modified || path_b == path_e) + if (opt.enable_iri || path_modified || u->fragment || host_modified || path_b == path_e) { /* If we suspect that a transformation has rendered what url_string might return different from URL_ENCODED, rebuild @@ -866,7 +914,7 @@ url_parse (const char *url, int *error) if (url_encoded == url) u->url = xstrdup (url); else - u->url = url_encoded; + u->url = (char *) url_encoded; } return u; @@ -874,7 +922,7 @@ url_parse (const char *url, int *error) error: /* Cleanup in case of error: */ if (url_encoded && url_encoded != url) - xfree (url_encoded); + xfree ((char *) url_encoded); /* Transmit the error code to the caller, if the caller wants to know. */ @@ -900,9 +948,9 @@ url_error (const char *url, int error_code) if ((p = strchr (scheme, ':'))) *p = '\0'; if (!strcasecmp (scheme, "https")) - asprintf (&error, _("HTTPS support not compiled in")); + error = aprintf (_("HTTPS support not compiled in")); else - asprintf (&error, _(parse_errors[error_code]), quote (scheme)); + error = aprintf (_(parse_errors[error_code]), quote (scheme)); xfree (scheme); return error; @@ -1243,7 +1291,9 @@ enum { filechr_control = 4 /* a control character, e.g. 0-31 */ }; -#define FILE_CHAR_TEST(c, mask) (filechr_table[(unsigned char)(c)] & (mask)) +#define FILE_CHAR_TEST(c, mask) \ + ((opt.restrict_files_nonascii && !c_isascii ((unsigned char)(c))) || \ + (filechr_table[(unsigned char)(c)] & (mask))) /* Shorthands for the table: */ #define U filechr_not_unix @@ -1527,11 +1577,30 @@ url_file_name (const struct url *u) if ((opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct) && !(file_exists_p (fname) && !file_non_directory_p (fname))) - return fname; + { + unique = fname; + } + else + { + unique = unique_name (fname, true); + if (unique != fname) + xfree (fname); + } + +/* On VMS, alter the name as required. */ +#ifdef __VMS + { + char *unique2; + + unique2 = ods_conform( unique); + if (unique2 != unique) + { + xfree (unique); + unique = unique2; + } + } +#endif /* def __VMS */ - unique = unique_name (fname, true); - if (unique != fname) - xfree (fname); return unique; } @@ -1969,12 +2038,12 @@ schemes_are_similar_p (enum url_scheme a, enum url_scheme b) static int getchar_from_escaped_string (const char *str, char *c) -{ +{ const char *p = str; assert (str && *str); assert (c); - + if (p[0] == '%') { if (!c_isxdigit(p[1]) || !c_isxdigit(p[2])) @@ -2024,7 +2093,7 @@ are_urls_equal (const char *u1, const char *u2) p += pp; q += qq; } - + return (*p == 0 && *q == 0 ? true : false); } @@ -2133,7 +2202,7 @@ test_append_uri_pathel() } test_array[] = { { "http://www.yoyodyne.com/path/", "somepage.html", false, "http://www.yoyodyne.com/path/somepage.html" }, }; - + for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) { struct growable dest;