@@ -67,12 +67,10 @@ static int url_decode_char(const char *q)
67
67
return val ;
68
68
}
69
69
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 )
71
71
{
72
72
const char * q = * query ;
73
- struct strbuf out ;
74
73
75
- strbuf_init (& out , 16 );
76
74
do {
77
75
unsigned char c = * q ;
78
76
@@ -86,33 +84,43 @@ static char *url_decode_internal(const char **query, const char *stop_at)
86
84
if (c == '%' ) {
87
85
int val = url_decode_char (q + 1 );
88
86
if (0 <= val ) {
89
- strbuf_addch (& out , val );
87
+ strbuf_addch (out , val );
90
88
q += 3 ;
91
89
continue ;
92
90
}
93
91
}
94
92
95
93
if (c == '+' )
96
- strbuf_addch (& out , ' ' );
94
+ strbuf_addch (out , ' ' );
97
95
else
98
- strbuf_addch (& out , c );
96
+ strbuf_addch (out , c );
99
97
q ++ ;
100
98
} while (1 );
101
99
* query = q ;
102
- return strbuf_detach (& out , NULL );
100
+ return strbuf_detach (out , NULL );
103
101
}
104
102
105
103
char * url_decode (const char * url )
106
104
{
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 );
108
114
}
109
115
110
116
char * url_decode_parameter_name (const char * * query )
111
117
{
112
- return url_decode_internal (query , "&=" );
118
+ struct strbuf out = STRBUF_INIT ;
119
+ return url_decode_internal (query , "&=" , & out );
113
120
}
114
121
115
122
char * url_decode_parameter_value (const char * * query )
116
123
{
117
- return url_decode_internal (query , "&" );
124
+ struct strbuf out = STRBUF_INIT ;
125
+ return url_decode_internal (query , "&" , & out );
118
126
}
0 commit comments