aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-06-09 13:11:12 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-06-09 13:11:12 +0300
commit8dc93b0834b25e71cc6307df2484ea4ef0b142db (patch)
tree23895532db278a9c98d3e9c4e39b5f4046c2df56
parent4993c1520285889790c505b77a5f34c0353e99fb (diff)
downloadlibmicrohttpd-8dc93b0834b25e71cc6307df2484ea4ef0b142db.tar.gz
libmicrohttpd-8dc93b0834b25e71cc6307df2484ea4ef0b142db.zip
base64 decoding: added more compact code version
Also added more base64 test sequencies
-rw-r--r--src/microhttpd/mhd_str.c98
-rw-r--r--src/microhttpd/test_str_base64.c47
2 files changed, 124 insertions, 21 deletions
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c
index ff482020..d32efc02 100644
--- a/src/microhttpd/mhd_str.c
+++ b/src/microhttpd/mhd_str.c
@@ -2199,18 +2199,68 @@ MHD_str_quote (const char *unquoted,
2199 2199
2200#ifdef BAUTH_SUPPORT 2200#ifdef BAUTH_SUPPORT
2201 2201
2202/*
2203 * MHD_BASE64_FUNC_VERSION
2204 * 1 = smallest,
2205 * 2 = medium,
2206 * 3 = fastest
2207 */
2208#ifndef MHD_BASE64_FUNC_VERSION
2209#ifdef MHD_FAVOR_SMALL_CODE
2210#define MHD_BASE64_FUNC_VERSION 1
2211#else /* ! MHD_FAVOR_SMALL_CODE */
2212#define MHD_BASE64_FUNC_VERSION 3
2213#endif /* ! MHD_FAVOR_SMALL_CODE */
2214#endif /* ! MHD_BASE64_FUNC_VERSION */
2215
2216#if MHD_BASE64_FUNC_VERSION < 1 || MHD_BASE64_FUNC_VERSION > 3
2217#error Wrong MHD_BASE64_FUNC_VERSION value
2218#endif /* MHD_BASE64_FUNC_VERSION < 1 || MHD_BASE64_FUNC_VERSION > 3 */
2219
2220#if MHD_BASE64_FUNC_VERSION == 3
2221#define MHD_base64_map_type_ int
2222#else /* MHD_BASE64_FUNC_VERSION < 3 */
2223#define MHD_base64_map_type_ int8_t
2224#endif /* MHD_BASE64_FUNC_VERSION < 3 */
2225
2226#if MHD_BASE64_FUNC_VERSION == 1
2227static MHD_base64_map_type_
2228base64_char_to_value_ (uint8_t c)
2229{
2230 if ('Z' >= c)
2231 {
2232 if ('A' <= c)
2233 return (MHD_base64_map_type_) (c - 'A') + 0;
2234 if ('0' <= c)
2235 {
2236 if ('9' >= c)
2237 return (MHD_base64_map_type_) (c - '0') + 52;
2238 if ('=' == c)
2239 return -2;
2240 return -1;
2241 }
2242 if ('+' == c)
2243 return 62;
2244 if ('/' == c)
2245 return 63;
2246 return -1;
2247 }
2248 if (('z' >= c) && ('a' <= c))
2249 return (MHD_base64_map_type_) (c - 'a') + 26;
2250 return -1;
2251}
2252
2253
2254#endif /* MHD_BASE64_FUNC_VERSION == 1 */
2255
2202size_t 2256size_t
2203MHD_base64_to_bin_n (const char *base64, 2257MHD_base64_to_bin_n (const char *base64,
2204 size_t base64_len, 2258 size_t base64_len,
2205 void *bin, 2259 void *bin,
2206 size_t bin_size) 2260 size_t bin_size)
2207{ 2261{
2208#ifndef MHD_FAVOR_SMALL_CODE 2262#if MHD_BASE64_FUNC_VERSION >= 2
2209#define map_type int 2263 static const MHD_base64_map_type_ map[] = {
2210#else /* MHD_FAVOR_SMALL_CODE */
2211#define map_type int8_t
2212#endif /* MHD_FAVOR_SMALL_CODE */
2213 static const map_type map[] = {
2214 /* -1 = invalid char, -2 = padding 2264 /* -1 = invalid char, -2 = padding
2215 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 2265 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2216 NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, */ 2266 NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, */
@@ -2276,7 +2326,7 @@ MHD_base64_to_bin_n (const char *base64,
2276 'x', 'y', 'z', '{', '|', '}', '~', DEL, */ 2326 'x', 'y', 'z', '{', '|', '}', '~', DEL, */
2277 49, 50, 51, -1, -1, -1, -1, -1 2327 49, 50, 51, -1, -1, -1, -1, -1
2278 2328
2279#ifndef MHD_FAVOR_SMALL_CODE 2329#if MHD_BASE64_FUNC_VERSION == 3
2280 , 2330 ,
2281 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80..8F */ 2331 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80..8F */
2282 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90..9F */ 2332 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90..9F */
@@ -2286,8 +2336,10 @@ MHD_base64_to_bin_n (const char *base64,
2286 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0..DF */ 2336 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0..DF */
2287 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0..EF */ 2337 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0..EF */
2288 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* F0..FF */ 2338 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* F0..FF */
2289#endif /* ! MHD_FAVOR_SMALL_CODE */ 2339#endif /* ! MHD_BASE64_FUNC_VERSION == 3 */
2290 }; 2340 };
2341#define base64_char_to_value_(c) map[(c)]
2342#endif /* MHD_BASE64_FUNC_VERSION >= 2 */
2291 const uint8_t *const in = (const uint8_t *) base64; 2343 const uint8_t *const in = (const uint8_t *) base64;
2292 uint8_t *const out = (uint8_t *) bin; 2344 uint8_t *const out = (uint8_t *) bin;
2293 size_t i; 2345 size_t i;
@@ -2302,16 +2354,16 @@ MHD_base64_to_bin_n (const char *base64,
2302 j = 0; 2354 j = 0;
2303 for (i = 0; i < (base64_len - 4); i += 4) 2355 for (i = 0; i < (base64_len - 4); i += 4)
2304 { 2356 {
2305#ifdef MHD_FAVOR_SMALL_CODE 2357#if MHD_BASE64_FUNC_VERSION == 2
2306 if (0 != (0x80 & (in[i] | in[i + 1] | in[i + 2] | in[i + 3]))) 2358 if (0 != (0x80 & (in[i] | in[i + 1] | in[i + 2] | in[i + 3])))
2307 return 0; 2359 return 0;
2308#endif /* MHD_FAVOR_SMALL_CODE */ 2360#endif /* MHD_BASE64_FUNC_VERSION == 2 */
2309 if (1) 2361 if (1)
2310 { 2362 {
2311 const map_type v1 = map[in[i + 0]]; 2363 const MHD_base64_map_type_ v1 = base64_char_to_value_ (in[i + 0]);
2312 const map_type v2 = map[in[i + 1]]; 2364 const MHD_base64_map_type_ v2 = base64_char_to_value_ (in[i + 1]);
2313 const map_type v3 = map[in[i + 2]]; 2365 const MHD_base64_map_type_ v3 = base64_char_to_value_ (in[i + 2]);
2314 const map_type v4 = map[in[i + 3]]; 2366 const MHD_base64_map_type_ v4 = base64_char_to_value_ (in[i + 3]);
2315 if ((0 > v1) || (0 > v2) || (0 > v3) || (0 > v4)) 2367 if ((0 > v1) || (0 > v2) || (0 > v3) || (0 > v4))
2316 return 0; 2368 return 0;
2317 out[j + 0] = (uint8_t) ((((uint8_t) v1) << 2) | (((uint8_t) v2) >> 4)); 2369 out[j + 0] = (uint8_t) ((((uint8_t) v1) << 2) | (((uint8_t) v2) >> 4));
@@ -2320,16 +2372,16 @@ MHD_base64_to_bin_n (const char *base64,
2320 } 2372 }
2321 j += 3; 2373 j += 3;
2322 } 2374 }
2323#ifdef MHD_FAVOR_SMALL_CODE 2375#if MHD_BASE64_FUNC_VERSION == 2
2324 if (0 != (0x80 & (in[i] | in[i + 1] | in[i + 2] | in[i + 3]))) 2376 if (0 != (0x80 & (in[i] | in[i + 1] | in[i + 2] | in[i + 3])))
2325 return 0; 2377 return 0;
2326#endif /* MHD_FAVOR_SMALL_CODE */ 2378#endif /* MHD_BASE64_FUNC_VERSION == 2 */
2327 if (1) 2379 if (1)
2328 { /* The last four chars block */ 2380 { /* The last four chars block */
2329 const map_type v1 = map[in[i + 0]]; 2381 const MHD_base64_map_type_ v1 = base64_char_to_value_ (in[i + 0]);
2330 const map_type v2 = map[in[i + 1]]; 2382 const MHD_base64_map_type_ v2 = base64_char_to_value_ (in[i + 1]);
2331 const map_type v3 = map[in[i + 2]]; 2383 const MHD_base64_map_type_ v3 = base64_char_to_value_ (in[i + 2]);
2332 const map_type v4 = map[in[i + 3]]; 2384 const MHD_base64_map_type_ v4 = base64_char_to_value_ (in[i + 3]);
2333 if ((0 > v1) || (0 > v2)) 2385 if ((0 > v1) || (0 > v2))
2334 return 0; /* Invalid char or padding at first two positions */ 2386 return 0; /* Invalid char or padding at first two positions */
2335 mhd_assert (j < bin_size); 2387 mhd_assert (j < bin_size);
@@ -2358,8 +2410,12 @@ MHD_base64_to_bin_n (const char *base64,
2358 out[j++] = (uint8_t) ((((uint8_t) v3) << 6) | (((uint8_t) v4))); 2410 out[j++] = (uint8_t) ((((uint8_t) v3) << 6) | (((uint8_t) v4)));
2359 } 2411 }
2360 return j; 2412 return j;
2361#undef map_type 2413#if MHD_BASE64_FUNC_VERSION >= 2
2414#undef base64_char_to_value_
2415#endif /* MHD_BASE64_FUNC_VERSION >= 2 */
2362} 2416}
2363 2417
2364 2418
2419#undef MHD_base64_map_type_
2420
2365#endif /* BAUTH_SUPPORT */ 2421#endif /* BAUTH_SUPPORT */
diff --git a/src/microhttpd/test_str_base64.c b/src/microhttpd/test_str_base64.c
index 1821d116..cc5afb5c 100644
--- a/src/microhttpd/test_str_base64.c
+++ b/src/microhttpd/test_str_base64.c
@@ -579,6 +579,53 @@ check_decode_bin (void)
579 "gUEAwIBAP/+/Q==", bin); 579 "gUEAwIBAP/+/Q==", bin);
580 } 580 }
581 581
582 if (1)
583 {
584 static const uint8_t bin[48] =
585 {0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8b, 0x30, 0xd3, 0x8f,
586 0x41, 0x14, 0x93, 0x51, 0x55, 0x97, 0x61, 0x96, 0x9b, 0x71, 0xd7, 0x9f,
587 0x82, 0x18, 0xa3, 0x92, 0x59, 0xa7, 0xa2, 0x9a, 0xab, 0xb2, 0xdb, 0xaf,
588 0xc3, 0x1c, 0xb3, 0xd3, 0x5d, 0xb7, 0xe3, 0x9e, 0xbb, 0xf3, 0xdf, 0xbf };
589 r += expect_decoded_arr ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
590 "abcdefghijklmnopqrstuvwxyz0123456789+/", bin);
591 }
592
593 if (1)
594 {
595 static const uint8_t bin[49] =
596 {0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8b, 0x30, 0xd3, 0x8f,
597 0x41, 0x14, 0x93, 0x51, 0x55, 0x97, 0x61, 0x96, 0x9b, 0x71, 0xd7, 0x9f,
598 0x82, 0x18, 0xa3, 0x92, 0x59, 0xa7, 0xa2, 0x9a, 0xab, 0xb2, 0xdb, 0xaf,
599 0xc3, 0x1c, 0xb3, 0xd3, 0x5d, 0xb7, 0xe3, 0x9e, 0xbb, 0xf3, 0xdf, 0xbf,
600 0x00 };
601 r += expect_decoded_arr ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
602 "abcdefghijklmnopqrstuvwxyz0123456789+/" \
603 "AA==", bin);
604 }
605
606 if (1)
607 {
608 static const uint8_t bin[48] =
609 {0xff, 0xef, 0x7c, 0xef, 0xae, 0x78, 0xdf, 0x6d, 0x74, 0xcf, 0x2c, 0x70,
610 0xbe, 0xeb, 0x6c, 0xae, 0xaa, 0x68, 0x9e, 0x69, 0x64, 0x8e, 0x28, 0x60,
611 0x7d, 0xe7, 0x5c, 0x6d, 0xa6, 0x58, 0x5d, 0x65, 0x54, 0x4d, 0x24, 0x50,
612 0x3c, 0xe3, 0x4c, 0x2c, 0xa2, 0x48, 0x1c, 0x61, 0x44, 0x0c, 0x20, 0x40 };
613 r += expect_decoded_arr ("/+9876543210zyxwvutsrqponmlkjihgfedcba" \
614 "ZYXWVUTSRQPONMLKJIHGFEDCBA", bin);
615 }
616
617 if (1)
618 {
619 static const uint8_t bin[49] =
620 {0xff, 0xef, 0x7c, 0xef, 0xae, 0x78, 0xdf, 0x6d, 0x74, 0xcf, 0x2c, 0x70,
621 0xbe, 0xeb, 0x6c, 0xae, 0xaa, 0x68, 0x9e, 0x69, 0x64, 0x8e, 0x28, 0x60,
622 0x7d, 0xe7, 0x5c, 0x6d, 0xa6, 0x58, 0x5d, 0x65, 0x54, 0x4d, 0x24, 0x50,
623 0x3c, 0xe3, 0x4c, 0x2c, 0xa2, 0x48, 0x1c, 0x61, 0x44, 0x0c, 0x20, 0x40,
624 0x00 };
625 r += expect_decoded_arr ("/+9876543210zyxwvutsrqponmlkjihgfedcba" \
626 "ZYXWVUTSRQPONMLKJIHGFEDCBAAA==", bin);
627 }
628
582 return r; 629 return r;
583} 630}
584 631