diff options
author | Dan Winship <danw@src.gnome.org> | 2003-03-27 23:37:47 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2003-03-27 23:37:47 +0800 |
commit | be9db81541bff178c5087a47becd5afc519afcb6 (patch) | |
tree | f9e15fc56ece03566b03b4d35d74b5fbbd4ba0bd /camel/camel-url.c | |
parent | b3293f0d99b13c1ee49f3605534ee3552cf19158 (diff) | |
download | gsoc2013-evolution-be9db81541bff178c5087a47becd5afc519afcb6.tar.gz gsoc2013-evolution-be9db81541bff178c5087a47becd5afc519afcb6.tar.zst gsoc2013-evolution-be9db81541bff178c5087a47becd5afc519afcb6.zip |
Like camel_url_encode, but works directly on an existing GString.
* camel-url.c (append_url_encoded): Like camel_url_encode, but
works directly on an existing GString.
(camel_url_to_string, output_param): Use it.
(camel_url_encode): Likewise. Remove "escape_unsafe" arg since the
"unsafe" chars are the ones that should *always* be escaped, and
the places we were passing FALSE were wrong.
(camel_url_decode): replace with a new version
* camel-file-utils.c (camel_file_util_safe_filename): Remove extra
arg to camel_url_encode.
* tests/misc/url.c (main): Add tests of basic URL parsing and
unparsing
svn path=/trunk/; revision=20545
Diffstat (limited to 'camel/camel-url.c')
-rw-r--r-- | camel/camel-url.c | 152 |
1 files changed, 79 insertions, 73 deletions
diff --git a/camel/camel-url.c b/camel/camel-url.c index a78ba44b6a..7b1c31db5c 100644 --- a/camel/camel-url.c +++ b/camel/camel-url.c @@ -4,7 +4,6 @@ /* * Authors: * Dan Winship <danw@ximian.com> - * Tiago Antào <tiagoantao@bigfoot.com> * Jeffrey Stedfast <fejj@ximian.com> * * Copyright 1999-2001 Ximian, Inc. (www.ximian.com) @@ -42,6 +41,8 @@ static void copy_param (GQuark key_id, gpointer data, gpointer user_data); static void output_param (GQuark key_id, gpointer data, gpointer user_data); +static void append_url_encoded (GString *str, const char *in, const char *extra_enc_chars); + /** * camel_url_new_with_base: * @base: a base URL @@ -304,7 +305,7 @@ char * camel_url_to_string (CamelURL *url, guint32 flags) { GString *str; - char *enc, *return_result; + char *return_result; /* IF YOU CHANGE ANYTHING IN THIS FUNCTION, RUN * tests/misc/url AFTERWARD. @@ -318,47 +319,35 @@ camel_url_to_string (CamelURL *url, guint32 flags) if (url->host) { g_string_append (str, "//"); if (url->user) { - enc = camel_url_encode (url->user, TRUE, ":;@/"); - g_string_append (str, enc); - g_free (enc); - } - if (url->authmech && *url->authmech) { - enc = camel_url_encode (url->authmech, TRUE, ":@/"); - g_string_append_printf (str, ";auth=%s", enc); - g_free (enc); - } - if (url->passwd && !(flags & CAMEL_URL_HIDE_PASSWORD)) { - enc = camel_url_encode (url->passwd, TRUE, "@/"); - g_string_append_printf (str, ":%s", enc); - g_free (enc); - } - if (url->host) { - enc = camel_url_encode (url->host, TRUE, ":/"); - g_string_append_printf (str, "%s%s", url->user ? "@" : "", enc); - g_free (enc); + append_url_encoded (str, url->user, ":;@/"); + if (url->authmech && *url->authmech) { + g_string_append (str, ";auth="); + append_url_encoded (str, url->authmech, ":@/"); + } + if (url->passwd && !(flags & CAMEL_URL_HIDE_PASSWORD)) { + g_string_append_c (str, ':'); + append_url_encoded (str, url->passwd, "@/"); + } + g_string_append_c (str, '@'); } + append_url_encoded (str, url->host, ":/"); if (url->port) g_string_append_printf (str, ":%d", url->port); if (!url->path && (url->params || url->query || url->fragment)) g_string_append_c (str, '/'); } - if (url->path) { - enc = camel_url_encode (url->path, FALSE, ";?#"); - g_string_append_printf (str, "%s", enc); - g_free (enc); - } + if (url->path) + append_url_encoded (str, url->path, ";?"); if (url->params && !(flags & CAMEL_URL_HIDE_PARAMS)) g_datalist_foreach (&url->params, output_param, str); if (url->query) { - enc = camel_url_encode (url->query, FALSE, "#"); - g_string_append_printf (str, "?%s", enc); - g_free (enc); + g_string_append_c (str, '?'); + append_url_encoded (str, url->query, NULL); } if (url->fragment) { - enc = camel_url_encode (url->fragment, FALSE, NULL); - g_string_append_printf (str, "#%s", enc); - g_free (enc); + g_string_append_c (str, '#'); + append_url_encoded (str, url->fragment, NULL); } return_result = str->str; @@ -371,15 +360,12 @@ static void output_param (GQuark key_id, gpointer data, gpointer user_data) { GString *str = user_data; - char *enc; - - enc = camel_url_encode (g_quark_to_string (key_id), FALSE, "?#"); - g_string_append_printf (str, ";%s", enc); - g_free (enc); + + g_string_append_c (str, ';'); + append_url_encoded (str, g_quark_to_string (key_id), "?="); if (*(char *)data) { - enc = camel_url_encode (data, FALSE, "?#"); - g_string_append_printf (str, "=%s", enc); - g_free (enc); + g_string_append_c (str, '='); + append_url_encoded (str, data, "?"); } } @@ -443,42 +429,63 @@ camel_url_get_param (CamelURL *url, const char *name) return g_datalist_get_data (&url->params, name); } +/* From RFC 2396 2.4.3, the characters that should always be encoded */ +static const char url_encoded_char[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 - 0x0f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x10 - 0x1f */ + 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ' ' - '/' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* '0' - '?' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* '@' - 'O' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 'P' - '_' */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* '`' - 'o' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* 'p' - 0x7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +static void +append_url_encoded (GString *str, const char *in, const char *extra_enc_chars) +{ + const unsigned char *s = (const unsigned char *)in; + + while (*s) { + if (url_encoded_char[*s] || + (extra_enc_chars && strchr (extra_enc_chars, *s))) + g_string_append_printf (str, "%%%02x", (int)*s++); + else + g_string_append_c (str, *s++); + } +} /** * camel_url_encode: * @part: a URL part - * @escape_unsafe: whether or not to %-escape "unsafe" characters. - * ("%#<>{}|\^~[]`) - * @escape_extra: additional characters to escape. + * @escape_extra: additional characters beyond " \"%#<>{}|\^[]`" + * to escape (or %NULL) * * This %-encodes the given URL part and returns the escaped version * in allocated memory, which the caller must free when it is done. **/ char * -camel_url_encode (const char *part, gboolean escape_unsafe, - const char *escape_extra) +camel_url_encode (const char *part, const char *escape_extra) { - char *work, *p; - - /* worst case scenario = 3 times the initial */ - p = work = g_malloc (3 * strlen (part) + 1); + GString *str; + char *encoded; - while (*part) { - if (((guchar) *part >= 127) || ((guchar) *part <= ' ') || - (escape_unsafe && strchr ("\"%#<>{}|\\^~[]`", *part)) || - (escape_extra && strchr (escape_extra, *part))) { - sprintf (p, "%%%.02hX", (guchar) *part++); - p += 3; - } else - *p++ = *part++; - } - *p = '\0'; + str = g_string_new (NULL); + append_url_encoded (str, part, escape_extra); + encoded = str->str; + g_string_free (str, FALSE); - return work; + return encoded; } -#define HEXVAL(c) (isdigit (c) ? (c) - '0' : tolower (c) - 'a' + 10) - /** * camel_url_decode: * @part: a URL part @@ -490,22 +497,21 @@ camel_url_encode (const char *part, gboolean escape_unsafe, void camel_url_decode (char *part) { - guchar *s, *d; + unsigned char *s, *d; - s = d = (guchar *)part; - while (*s) { - if (*s == '%') { - if (isxdigit (s[1]) && isxdigit (s[2])) { - *d++ = HEXVAL (s[1]) * 16 + HEXVAL (s[2]); - s += 3; - } else - *d++ = *s++; +#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) + + s = d = (unsigned char *)part; + do { + if (*s == '%' && s[1] && s[2]) { + *d++ = (XDIGIT (s[1]) << 4) + XDIGIT (s[2]); + s += 2; } else - *d++ = *s++; - } - *d = '\0'; + *d++ = *s; + } while (*s++); } + guint camel_url_hash (const void *v) { |