@@ -67,12 +67,10 @@ static int url_decode_char(const char *q)
6767 return val ;
6868}
6969
70- static char * url_decode_internal (const char * * query , const char * stop_at )
70+ static char * url_decode_internal (const char * * query , const char * stop_at , struct strbuf * out )
7171{
7272 const char * q = * query ;
73- struct strbuf out ;
7473
75- strbuf_init (& out , 16 );
7674 do {
7775 unsigned char c = * q ;
7876
@@ -86,33 +84,43 @@ static char *url_decode_internal(const char **query, const char *stop_at)
8684 if (c == '%' ) {
8785 int val = url_decode_char (q + 1 );
8886 if (0 <= val ) {
89- strbuf_addch (& out , val );
87+ strbuf_addch (out , val );
9088 q += 3 ;
9189 continue ;
9290 }
9391 }
9492
9593 if (c == '+' )
96- strbuf_addch (& out , ' ' );
94+ strbuf_addch (out , ' ' );
9795 else
98- strbuf_addch (& out , c );
96+ strbuf_addch (out , c );
9997 q ++ ;
10098 } while (1 );
10199 * query = q ;
102- return strbuf_detach (& out , NULL );
100+ return strbuf_detach (out , NULL );
103101}
104102
105103char * url_decode (const char * url )
106104{
107- return url_decode_internal (& url , NULL );
105+ struct strbuf out = STRBUF_INIT ;
106+ const char * slash = strchr (url , '/' );
107+
108+ /* Skip protocol part if present */
109+ if (slash && url < slash ) {
110+ strbuf_add (& out , url , slash - url );
111+ url = slash ;
112+ }
113+ return url_decode_internal (& url , NULL , & out );
108114}
109115
110116char * url_decode_parameter_name (const char * * query )
111117{
112- return url_decode_internal (query , "&=" );
118+ struct strbuf out = STRBUF_INIT ;
119+ return url_decode_internal (query , "&=" , & out );
113120}
114121
115122char * url_decode_parameter_value (const char * * query )
116123{
117- return url_decode_internal (query , "&" );
124+ struct strbuf out = STRBUF_INIT ;
125+ return url_decode_internal (query , "&" , & out );
118126}
0 commit comments