Commit 2b405629 authored by Pekka Pessi's avatar Pekka Pessi

url.c: fixed escaping of '/' %2F, ';' %3B and '

Thanks for Fabio Margarido for reporting this bug.

darcs-hash:20070831160809-65a35-72d12a60dc25bdb92d107460eff9a22c99ec2ecd.gz
parent 0875d496
......@@ -134,10 +134,12 @@ int test_quote(void)
d = url_as_string(home, u); TEST_1(d);
TEST_S(d, c);
d = "http://&=+$,;:&=+$,;@host:8080/foo;param=+$,/:@&;another=@"
d = "http://&=+$,;:&=+$,;@host:8080/foo%2F%3B%3D"
";param=+$,%2f%3b%3d/bar;param=:@&;another=@"
"?query=" RESERVED;
u = url_hdup(home, (url_t *)d); TEST_1(u);
TEST_S(u->url_user, "&=+$,;"); TEST_S(u->url_password, "&=+$,;");
TEST_S(u->url_path, "foo%2F%3B%3D;param=+$,%2F%3B%3D/bar;param=:@&;another=@");
url_digest(hash1, sizeof(hash1), u, NULL);
url_digest(hash2, sizeof(hash2), (url_t const *)d, NULL);
TEST(memcmp(hash1, hash2, sizeof(hash1)), 0);
......@@ -242,7 +244,7 @@ int test_sip(void)
"sip:user:pass@host:32;param=1"
"?From=foo@bar&To=bar@baz#unf";
char sip2url[] =
"sip:user/path;tel-param:pass@host:32;param=1"
"sip:user/path;tel-param:pass@host:32;param=1%3d%3d1"
"?From=foo@bar&To=bar@baz#unf";
char sip2[sizeof(sipurl) + 32];
char sipsurl[] =
......@@ -305,6 +307,7 @@ int test_sip(void)
TEST_1(tst = su_strdup(home, sip2url));
TEST_1(url_d(url, tst) == 0);
TEST_S(url->url_user, "user/path;tel-param");
TEST_S(url->url_params, "param=1%3D%3D1");
TEST_S(url_query_as_header_string(home, url->url_headers),
"From:foo@bar\nTo:bar@baz");
......
......@@ -129,6 +129,8 @@
else if (a < 128) \
mask96 &= ~(1U << (127 - a))
#define NUL '\0'
#define NULNULNUL '\0', '\0', '\0'
#define RMASK1 0xbe19003f
#define RMASK2 0x8000001e
......@@ -141,8 +143,10 @@
/* Internal prototypes */
static char *url_canonize(char *d, char const *s, size_t n,
char syn1, char syn2, char syn3,
char const allowed[]);
static char *url_canonize2(char *d, char const *s, size_t n,
char syn1, char syn2, char syn3,
unsigned m32, unsigned m64, unsigned m96);
static int url_tel_cmp_numbers(char const *A, char const *B);
......@@ -322,18 +326,21 @@ char *url_unescape(char *d, char const *s)
/** Canonize a URL component */
static
char *url_canonize(char *d, char const *s, size_t n, char const allowed[])
char *url_canonize(char *d, char const *s, size_t n,
char syn1, char syn2, char syn3,
char const allowed[])
{
unsigned mask32 = 0xbe19003f, mask64 = 0x8000001e, mask96 = 0x8000001d;
MASKS_WITH_ALLOWED(allowed, mask32, mask64, mask96);
return url_canonize2(d, s, n, mask32, mask64, mask96);
return url_canonize2(d, s, n, syn1, syn2, syn3, mask32, mask64, mask96);
}
/** Canonize a URL component (with precomputed mask) */
static
char *url_canonize2(char *d, char const * const s, size_t n,
char *url_canonize2(char *d, char const * const s, size_t n,
char syn1, char syn2, char syn3,
unsigned m32, unsigned m64, unsigned m96)
{
size_t i = 0;
......@@ -347,7 +354,7 @@ char *url_canonize2(char *d, char const * const s, size_t n,
unsigned char c = s[i], h1, h2;
if (c != '%') {
if (IS_EXCLUDED(c, m32, m64, m96))
if (c != syn1 && c != syn2 && c != syn3 && IS_EXCLUDED(c, m32, m64, m96))
return NULL;
*d = c;
continue;
......@@ -393,7 +400,7 @@ char *url_canonize2(char *d, char const * const s, size_t n,
* be escaped.
*/
static
char *url_canonize3(char *d, char const * const s, size_t n,
char *url_canonize3(char *d, char const * const s, size_t n,
unsigned m32, unsigned m64, unsigned m96)
{
size_t i = 0;
......@@ -575,7 +582,7 @@ int _url_d(url_t *url, char *s)
char *scheme;
url->url_scheme = scheme = s; s[n] = '\0'; s = s + n + 1;
if (!(scheme = url_canonize(scheme, scheme, SIZE_MAX, "+")))
if (!(scheme = url_canonize(scheme, scheme, SIZE_MAX, NULNULNUL, "+")))
return -1;
n = scheme - url->url_scheme;
......@@ -694,7 +701,7 @@ int _url_d(url_t *url, char *s)
case url_file:
case url_rtsp:
case url_rtspu:
if (!url_canonize2(port, port, SIZE_MAX, RESERVED_MASK))
if (!url_canonize2(port, port, SIZE_MAX, NULNULNUL, RESERVED_MASK))
return -1;
/* Check that port is really numeric or wildcard */
......@@ -758,14 +765,14 @@ int url_d(url_t *url, char *s)
# define SIP_USER_UNRESERVED "&=+$,;?/"
s = (char *)url->url_user;
if (s && !url_canonize(s, s, SIZE_MAX, SIP_USER_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, NULNULNUL, SIP_USER_UNRESERVED))
return -1;
/* Having different charset in user and password does not make sense */
/* but that is how it is defined in RFC 3261 */
# define SIP_PASS_UNRESERVED "&=+$,"
s = (char *)url->url_password;
if (s && !url_canonize(s, s, SIZE_MAX, SIP_PASS_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, NULNULNUL, SIP_PASS_UNRESERVED))
return -1;
}
......@@ -773,31 +780,31 @@ int url_d(url_t *url, char *s)
# define USER_UNRESERVED "&=+$,;"
s = (char *)url->url_user;
if (s && !url_canonize(s, s, SIZE_MAX, USER_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, NULNULNUL, USER_UNRESERVED))
return -1;
# define PASS_UNRESERVED "&=+$,;:"
s = (char *)url->url_password;
if (s && !url_canonize(s, s, SIZE_MAX, PASS_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, NULNULNUL, PASS_UNRESERVED))
return -1;
}
s = (char *)url->url_host;
if (s && !url_canonize2(s, s, SIZE_MAX, RESERVED_MASK))
if (s && !url_canonize2(s, s, SIZE_MAX, NULNULNUL, RESERVED_MASK))
return -1;
/* port is canonized by _url_d() */
/* Allow all URI characters but ? and ; */
# define PATH_UNRESERVED "/:@&=+$,"
# define PATH_UNRESERVED ":@&+$,"
s = (char *)url->url_path;
if (s && !url_canonize(s, s, SIZE_MAX, PATH_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, '/', ';', '=', PATH_UNRESERVED))
return -1;
/* Allow all URI characters but ? */
# define PARAMS_UNRESERVED ";" PATH_UNRESERVED
# define PARAMS_UNRESERVED ":@&+$,"
s = (char *)url->url_params;
if (s && !url_canonize(s, s, SIZE_MAX, PARAMS_UNRESERVED))
if (s && !url_canonize(s, s, SIZE_MAX, ';', '=', NUL, PARAMS_UNRESERVED))
return -1;
/* Unhex alphanumeric and unreserved URI characters */
......@@ -807,7 +814,7 @@ int url_d(url_t *url, char *s)
/* Allow all URI characters (including reserved ones) */
s = (char *)url->url_fragment;
if (s && !url_canonize2(s, s, SIZE_MAX, URIC_MASK))
if (s && !url_canonize2(s, s, SIZE_MAX, NULNULNUL, URIC_MASK))
return -1;
return 0;
......@@ -1927,7 +1934,7 @@ void url_string_update(su_md5_t *md5, char const *s)
su_md5_update(md5, ":", 1);
}
else if (n && s[n] == ':' ) {
at = url_canonize(schema, s, n, "+");
at = url_canonize(schema, s, n, NULNULNUL, "+");
type = url_get_type(schema, at - schema);
su_md5_iupdate(md5, schema, at - schema);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment