From 7877619f856a04af0519e92780b1d6674a8ff3f7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 15 Jun 2013 23:47:02 +0200 Subject: dotdot: introducing dot file path cleanup RFC3986 details how a path part passed in as part of a URI should be "cleaned" from dot sequences before getting used. The described algorithm is now implemented in lib/dotdot.c with the accompanied test case in test 1395. Bug: http://curl.haxx.se/bug/view.cgi?id=1200 Reported-by: Alex Vinnik --- lib/url.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7ba496986..e1c9dffe2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -124,6 +124,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "conncache.h" #include "multihandle.h" #include "pipeline.h" +#include "dotdot.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -3674,7 +3675,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, char protobuf[16]; const char *protop; CURLcode result; - bool fix_slash = FALSE; + bool rebuild_url = FALSE; *prot_missing = FALSE; @@ -3825,14 +3826,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, memcpy(path+1, query, hostlen); path[0]='/'; /* prepend the missing slash */ - fix_slash = TRUE; + rebuild_url = TRUE; *query=0; /* now cut off the hostname at the ? */ } else if(!path[0]) { /* if there's no path set, use a single slash */ strcpy(path, "/"); - fix_slash = TRUE; + rebuild_url = TRUE; } /* If the URL is malformatted (missing a '/' after hostname before path) we @@ -3845,17 +3846,30 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, is bigger than the path. Use +1 to move the zero byte too. */ memmove(&path[1], path, strlen(path)+1); path[0] = '/'; - fix_slash = TRUE; + rebuild_url = TRUE; + } + else { + /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ + char *newp = Curl_dedotdotify(path); + + if(strcmp(newp, path)) { + rebuild_url = TRUE; + free(data->state.pathbuffer); + data->state.pathbuffer = newp; + data->state.path = newp; + path = newp; + } + else + free(newp); } - /* - * "fix_slash" means that the URL was malformatted so we need to generate an - * updated version with the new slash inserted at the right place! We need - * the corrected URL when communicating over HTTP proxy and we don't know at - * this point if we're using a proxy or not. + * "rebuild_url" means that one or more URL components have been modified so + * we need to generate an updated full version. We need the corrected URL + * when communicating over HTTP proxy and we don't know at this point if + * we're using a proxy or not. */ - if(fix_slash) { + if(rebuild_url) { char *reurl; size_t plen = strlen(path); /* new path, should be 1 byte longer than @@ -3878,6 +3892,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, data->change.url_alloc = FALSE; } + infof(data, "Rebuilt URL to: %s\n", reurl); + data->change.url = reurl; data->change.url_alloc = TRUE; /* free this later */ } -- cgit v1.2.3