diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-09-11 21:04:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-09-11 21:04:02 +0200 |
commit | dd1061b6a79b0161597799e825bfefc27993ace5 (patch) | |
tree | f7099078291da669907c5e3f428c10af27a54417 /libbb/percent_decode.c | |
parent | 5126cf9a15f9e5c3986be0fc2743b63adcc6b1fb (diff) | |
download | busybox-w32-dd1061b6a79b0161597799e825bfefc27993ace5.tar.gz busybox-w32-dd1061b6a79b0161597799e825bfefc27993ace5.tar.bz2 busybox-w32-dd1061b6a79b0161597799e825bfefc27993ace5.zip |
wget: URL-decode user:password before base64-encoding it into auth hdr. Closes 3625.
function old new delta
percent_decode_in_place - 152 +152
parse_url 304 317 +13
handle_incoming_and_exit 2795 2798 +3
httpd_main 763 760 -3
decodeString 152 - -152
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 2/1 up/down: 168/-155) Total: 13 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/percent_decode.c')
-rw-r--r-- | libbb/percent_decode.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/libbb/percent_decode.c b/libbb/percent_decode.c new file mode 100644 index 000000000..9a9d80c4a --- /dev/null +++ b/libbb/percent_decode.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
4 | */ | ||
5 | |||
6 | //kbuild:lib-y += percent_decode.o | ||
7 | |||
8 | #include "libbb.h" | ||
9 | |||
10 | static unsigned hex_to_bin(unsigned char c) | ||
11 | { | ||
12 | unsigned v; | ||
13 | |||
14 | v = c - '0'; | ||
15 | if (v <= 9) | ||
16 | return v; | ||
17 | /* c | 0x20: letters to lower case, non-letters | ||
18 | * to (potentially different) non-letters */ | ||
19 | v = (unsigned)(c | 0x20) - 'a'; | ||
20 | if (v <= 5) | ||
21 | return v + 10; | ||
22 | return ~0; | ||
23 | /* For testing: | ||
24 | void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } | ||
25 | int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); | ||
26 | t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } | ||
27 | */ | ||
28 | } | ||
29 | |||
30 | char* FAST_FUNC percent_decode_in_place(char *str, int strict) | ||
31 | { | ||
32 | /* note that decoded string is always shorter than original */ | ||
33 | char *src = str; | ||
34 | char *dst = str; | ||
35 | char c; | ||
36 | |||
37 | while ((c = *src++) != '\0') { | ||
38 | unsigned v; | ||
39 | |||
40 | if (!strict && c == '+') { | ||
41 | *dst++ = ' '; | ||
42 | continue; | ||
43 | } | ||
44 | if (c != '%') { | ||
45 | *dst++ = c; | ||
46 | continue; | ||
47 | } | ||
48 | v = hex_to_bin(src[0]); | ||
49 | if (v > 15) { | ||
50 | bad_hex: | ||
51 | if (strict) | ||
52 | return NULL; | ||
53 | *dst++ = '%'; | ||
54 | continue; | ||
55 | } | ||
56 | v = (v * 16) | hex_to_bin(src[1]); | ||
57 | if (v > 255) | ||
58 | goto bad_hex; | ||
59 | if (strict && (v == '/' || v == '\0')) { | ||
60 | /* caller takes it as indication of invalid | ||
61 | * (dangerous wrt exploits) chars */ | ||
62 | return str + 1; | ||
63 | } | ||
64 | *dst++ = v; | ||
65 | src += 2; | ||
66 | } | ||
67 | *dst = '\0'; | ||
68 | return str; | ||
69 | } | ||