aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-10-28 16:15:00 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-10-28 16:15:00 +0200
commite6094d95b5d5a1a4c76aff99d89c8a4f44c5d59a (patch)
tree6fa00e6b32449af762e0b0e8b5d9d6e34c529de3
parent73d249e704cfdf8632c120599c1ddfeceb81dd32 (diff)
downloadbusybox-w32-e6094d95b5d5a1a4c76aff99d89c8a4f44c5d59a.tar.gz
busybox-w32-e6094d95b5d5a1a4c76aff99d89c8a4f44c5d59a.tar.bz2
busybox-w32-e6094d95b5d5a1a4c76aff99d89c8a4f44c5d59a.zip
libbb: shrink base64 decoding a bit
function old new delta bb_uuenc_tbl_base64 67 66 -1 decode_base64 182 161 -21 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/uuencode.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/libbb/uuencode.c b/libbb/uuencode.c
index 46ca79654..f7b248492 100644
--- a/libbb/uuencode.c
+++ b/libbb/uuencode.c
@@ -10,7 +10,7 @@
10#include "libbb.h" 10#include "libbb.h"
11 11
12/* Conversion table. for base 64 */ 12/* Conversion table. for base 64 */
13const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = { 13const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = {
14 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 14 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
15 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 15 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
16 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 16 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
@@ -20,7 +20,7 @@ const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = {
20 'w', 'x', 'y', 'z', '0', '1', '2', '3', 20 'w', 'x', 'y', 'z', '0', '1', '2', '3',
21 '4', '5', '6', '7', '8', '9', '+', '/', 21 '4', '5', '6', '7', '8', '9', '+', '/',
22 '=' /* termination character */, 22 '=' /* termination character */,
23 '\n', '\0' /* needed for uudecode.c */ 23 '\0' /* needed for uudecode.c only */
24}; 24};
25 25
26const char bb_uuenc_tbl_std[65] ALIGN1 = { 26const char bb_uuenc_tbl_std[65] ALIGN1 = {
@@ -77,7 +77,7 @@ void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl
77 * 77 *
78 * Returns: pointer to the undecoded part of source. 78 * Returns: pointer to the undecoded part of source.
79 * If points to '\0', then the source was fully decoded. 79 * If points to '\0', then the source was fully decoded.
80 * (*dst): advanced past the last written byte. 80 * (*pp_dst): advanced past the last written byte.
81 */ 81 */
82const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) 82const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
83{ 83{
@@ -85,10 +85,10 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
85 const char *src_tail; 85 const char *src_tail;
86 86
87 while (1) { 87 while (1) {
88 unsigned char translated[4]; 88 unsigned char six_bit[4];
89 int count = 0; 89 int count = 0;
90 90
91 /* Process one group of 4 chars */ 91 /* Fetch up to four 6-bit values */
92 src_tail = src; 92 src_tail = src;
93 while (count < 4) { 93 while (count < 4) {
94 char *table_ptr; 94 char *table_ptr;
@@ -97,8 +97,8 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
97 /* Get next _valid_ character. 97 /* Get next _valid_ character.
98 * bb_uuenc_tbl_base64[] contains this string: 98 * bb_uuenc_tbl_base64[] contains this string:
99 * 0 1 2 3 4 5 6 99 * 0 1 2 3 4 5 6
100 * 012345678901234567890123456789012345678901234567890123456789012345 100 * 01234567890123456789012345678901234567890123456789012345678901234
101 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" 101 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
102 */ 102 */
103 do { 103 do {
104 ch = *src; 104 ch = *src;
@@ -117,33 +117,37 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
117 src++; 117 src++;
118 table_ptr = strchr(bb_uuenc_tbl_base64, ch); 118 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
119//TODO: add BASE64_FLAG_foo to die on bad char? 119//TODO: add BASE64_FLAG_foo to die on bad char?
120//Note that then we may need to still allow '\r' (for mail processing)
121 } while (!table_ptr); 120 } while (!table_ptr);
122 121
123 /* Convert encoded character to decimal */ 122 /* Convert encoded character to decimal */
124 ch = table_ptr - bb_uuenc_tbl_base64; 123 ch = table_ptr - bb_uuenc_tbl_base64;
125 124
126 if (ch == 65) { /* '\n' */
127 continue;
128 }
129 /* ch is 64 if char was '=', otherwise 0..63 */ 125 /* ch is 64 if char was '=', otherwise 0..63 */
130 translated[count] = ch & 63; /* 64 -> 0 */ 126 if (ch == 64)
131 if (ch == 64) { /* '=' */
132 break; 127 break;
133 } 128 six_bit[count] = ch;
134 count++; 129 count++;
135 } 130 }
136 131
137 /* Merge 6 bit chars to 8 bit. 132 /* Transform 6-bit values to 8-bit ones.
138 * count can be < 4 when we decode the tail: 133 * count can be < 4 when we decode the tail:
139 * "eQ==" -> "y", not "y NUL NUL" 134 * "eQ==" -> "y", not "y NUL NUL".
135 * Note that (count > 1) is always true,
136 * "x===" encoding is not valid:
137 * even a single zero byte encodes as "AA==".
138 * However, with current logic we come here with count == 1
139 * when we decode "==" tail.
140 */ 140 */
141 if (count > 1) 141 if (count > 1)
142 *dst++ = translated[0] << 2 | translated[1] >> 4; 142 *dst++ = six_bit[0] << 2 | six_bit[1] >> 4;
143 if (count > 2) 143 if (count > 2)
144 *dst++ = translated[1] << 4 | translated[2] >> 2; 144 *dst++ = six_bit[1] << 4 | six_bit[2] >> 2;
145 if (count > 3) 145 if (count > 3)
146 *dst++ = translated[2] << 6 | translated[3]; 146 *dst++ = six_bit[2] << 6 | six_bit[3];
147 /* Note that if we decode "AA==" and ate first '=',
148 * we just decoded one char (count == 2) and now we'll
149 * do the loop once more to decode second '='.
150 */
147 } /* while (1) */ 151 } /* while (1) */
148 ret: 152 ret:
149 *pp_dst = dst; 153 *pp_dst = dst;