packages: clean up the package folder
[openwrt/svn-archive/archive.git] / package / utils / busybox / patches / 004-upstream-percent_decode_in_place.patch
1 http://git.busybox.net/busybox/commit/?id=dd1061b6a79b0161597799e825bfefc27993ace5
2
3 From dd1061b6a79b0161597799e825bfefc27993ace5 Mon Sep 17 00:00:00 2001
4 From: Denys Vlasenko <vda.linux@googlemail.com>
5 Date: Sun, 11 Sep 2011 21:04:02 +0200
6 Subject: [PATCH] wget: URL-decode user:password before base64-encoding it into auth hdr. Closes 3625.
7
8 function old new delta
9 percent_decode_in_place - 152 +152
10 parse_url 304 317 +13
11 handle_incoming_and_exit 2795 2798 +3
12 httpd_main 763 760 -3
13 decodeString 152 - -152
14 ------------------------------------------------------------------------------
15 (add/remove: 2/1 grow/shrink: 2/1 up/down: 168/-155) Total: 13 bytes
16
17 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
18
19 --- a/include/libbb.h
20 +++ b/include/libbb.h
21 @@ -1570,6 +1570,15 @@ int starts_with_cpu(const char *str) FAS
22 unsigned get_cpu_count(void) FAST_FUNC;
23
24
25 +/* Use strict=1 if you process input from untrusted source:
26 + * it will return NULL on invalid %xx (bad hex chars)
27 + * and str + 1 if decoded char is / or NUL.
28 + * In non-strict mode, it always succeeds (returns str),
29 + * and also it additionally decoded '+' to space.
30 + */
31 +char *percent_decode_in_place(char *str, int strict) FAST_FUNC;
32 +
33 +
34 extern const char bb_uuenc_tbl_base64[];
35 extern const char bb_uuenc_tbl_std[];
36 void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
37 --- /dev/null
38 +++ b/libbb/percent_decode.c
39 @@ -0,0 +1,69 @@
40 +/* vi: set sw=4 ts=4: */
41 +/*
42 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
43 + */
44 +
45 +//kbuild:lib-y += percent_decode.o
46 +
47 +#include "libbb.h"
48 +
49 +static unsigned hex_to_bin(unsigned char c)
50 +{
51 + unsigned v;
52 +
53 + v = c - '0';
54 + if (v <= 9)
55 + return v;
56 + /* c | 0x20: letters to lower case, non-letters
57 + * to (potentially different) non-letters */
58 + v = (unsigned)(c | 0x20) - 'a';
59 + if (v <= 5)
60 + return v + 10;
61 + return ~0;
62 +/* For testing:
63 +void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }
64 +int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
65 +t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
66 +*/
67 +}
68 +
69 +char* FAST_FUNC percent_decode_in_place(char *str, int strict)
70 +{
71 + /* note that decoded string is always shorter than original */
72 + char *src = str;
73 + char *dst = str;
74 + char c;
75 +
76 + while ((c = *src++) != '\0') {
77 + unsigned v;
78 +
79 + if (!strict && c == '+') {
80 + *dst++ = ' ';
81 + continue;
82 + }
83 + if (c != '%') {
84 + *dst++ = c;
85 + continue;
86 + }
87 + v = hex_to_bin(src[0]);
88 + if (v > 15) {
89 + bad_hex:
90 + if (strict)
91 + return NULL;
92 + *dst++ = '%';
93 + continue;
94 + }
95 + v = (v * 16) | hex_to_bin(src[1]);
96 + if (v > 255)
97 + goto bad_hex;
98 + if (strict && (v == '/' || v == '\0')) {
99 + /* caller takes it as indication of invalid
100 + * (dangerous wrt exploits) chars */
101 + return str + 1;
102 + }
103 + *dst++ = v;
104 + src += 2;
105 + }
106 + *dst = '\0';
107 + return str;
108 +}
109 --- a/networking/httpd.c
110 +++ b/networking/httpd.c
111 @@ -820,78 +820,6 @@ static char *encodeString(const char *st
112 }
113 #endif
114
115 -/*
116 - * Given a URL encoded string, convert it to plain ascii.
117 - * Since decoding always makes strings smaller, the decode is done in-place.
118 - * Thus, callers should xstrdup() the argument if they do not want the
119 - * argument modified. The return is the original pointer, allowing this
120 - * function to be easily used as arguments to other functions.
121 - *
122 - * string The first string to decode.
123 - * option_d 1 if called for httpd -d
124 - *
125 - * Returns a pointer to the decoded string (same as input).
126 - */
127 -static unsigned hex_to_bin(unsigned char c)
128 -{
129 - unsigned v;
130 -
131 - v = c - '0';
132 - if (v <= 9)
133 - return v;
134 - /* c | 0x20: letters to lower case, non-letters
135 - * to (potentially different) non-letters */
136 - v = (unsigned)(c | 0x20) - 'a';
137 - if (v <= 5)
138 - return v + 10;
139 - return ~0;
140 -/* For testing:
141 -void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }
142 -int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
143 -t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
144 -*/
145 -}
146 -static char *decodeString(char *orig, int option_d)
147 -{
148 - /* note that decoded string is always shorter than original */
149 - char *string = orig;
150 - char *ptr = string;
151 - char c;
152 -
153 - while ((c = *ptr++) != '\0') {
154 - unsigned v;
155 -
156 - if (option_d && c == '+') {
157 - *string++ = ' ';
158 - continue;
159 - }
160 - if (c != '%') {
161 - *string++ = c;
162 - continue;
163 - }
164 - v = hex_to_bin(ptr[0]);
165 - if (v > 15) {
166 - bad_hex:
167 - if (!option_d)
168 - return NULL;
169 - *string++ = '%';
170 - continue;
171 - }
172 - v = (v * 16) | hex_to_bin(ptr[1]);
173 - if (v > 255)
174 - goto bad_hex;
175 - if (!option_d && (v == '/' || v == '\0')) {
176 - /* caller takes it as indication of invalid
177 - * (dangerous wrt exploits) chars */
178 - return orig + 1;
179 - }
180 - *string++ = v;
181 - ptr += 2;
182 - }
183 - *string = '\0';
184 - return orig;
185 -}
186 -
187 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
188 /*
189 * Decode a base64 data stream as per rfc1521.
190 @@ -1949,7 +1877,7 @@ static void handle_incoming_and_exit(con
191 }
192
193 /* Decode URL escape sequences */
194 - tptr = decodeString(urlcopy, 0);
195 + tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1);
196 if (tptr == NULL)
197 send_headers_and_exit(HTTP_BAD_REQUEST);
198 if (tptr == urlcopy + 1) {
199 @@ -2408,7 +2336,7 @@ int httpd_main(int argc UNUSED_PARAM, ch
200 , &verbose
201 );
202 if (opt & OPT_DECODE_URL) {
203 - fputs(decodeString(url_for_decode, 1), stdout);
204 + fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout);
205 return 0;
206 }
207 #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
208 --- a/networking/wget.c
209 +++ b/networking/wget.c
210 @@ -298,8 +298,13 @@ static void parse_url(const char *src_ur
211
212 sp = strrchr(h->host, '@');
213 if (sp != NULL) {
214 - h->user = h->host;
215 + // URL-decode "user:password" string before base64-encoding:
216 + // wget http://test:my%20pass@example.com should send
217 + // Authorization: Basic dGVzdDpteSBwYXNz
218 + // which decodes to "test:my pass".
219 + // Standard wget and curl do this too.
220 *sp = '\0';
221 + h->user = percent_decode_in_place(h->host, /*strict:*/ 0);
222 h->host = sp + 1;
223 }
224
225 @@ -661,12 +666,6 @@ static void download_one_url(const char
226
227 #if ENABLE_FEATURE_WGET_AUTHENTICATION
228 if (target.user) {
229 -//TODO: URL-decode "user:password" string before base64-encoding:
230 -//wget http://test:my%20pass@example.com should send
231 -// Authorization: Basic dGVzdDpteSBwYXNz
232 -//which decodes to "test:my pass", instead of what we send now:
233 -// Authorization: Basic dGVzdDpteSUyMHBhc3M=
234 -//Can reuse decodeString() from httpd.c
235 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
236 base64enc(target.user));
237 }