lantiq: Tune the XWAY subtarget cflags
[openwrt.git] / package / 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                 }