diff options
Diffstat (limited to 'gl/base64.c')
-rw-r--r-- | gl/base64.c | 338 |
1 files changed, 169 insertions, 169 deletions
diff --git a/gl/base64.c b/gl/base64.c index 42ccc9c2..d99e175f 100644 --- a/gl/base64.c +++ b/gl/base64.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* base64.c -- Encode binary data using printable characters. | 1 | /* base64.c -- Encode binary data using printable characters. |
2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software | 2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006, 2009, 2010 Free Software |
3 | Foundation, Inc. | 3 | Foundation, Inc. |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -67,7 +67,7 @@ to_uchar (char ch) | |||
67 | terminate the output buffer. */ | 67 | terminate the output buffer. */ |
68 | void | 68 | void |
69 | base64_encode (const char *restrict in, size_t inlen, | 69 | base64_encode (const char *restrict in, size_t inlen, |
70 | char *restrict out, size_t outlen) | 70 | char *restrict out, size_t outlen) |
71 | { | 71 | { |
72 | static const char b64str[64] = | 72 | static const char b64str[64] = |
73 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 73 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
@@ -76,27 +76,27 @@ base64_encode (const char *restrict in, size_t inlen, | |||
76 | { | 76 | { |
77 | *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f]; | 77 | *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f]; |
78 | if (!--outlen) | 78 | if (!--outlen) |
79 | break; | 79 | break; |
80 | *out++ = b64str[((to_uchar (in[0]) << 4) | 80 | *out++ = b64str[((to_uchar (in[0]) << 4) |
81 | + (--inlen ? to_uchar (in[1]) >> 4 : 0)) | 81 | + (--inlen ? to_uchar (in[1]) >> 4 : 0)) |
82 | & 0x3f]; | 82 | & 0x3f]; |
83 | if (!--outlen) | 83 | if (!--outlen) |
84 | break; | 84 | break; |
85 | *out++ = | 85 | *out++ = |
86 | (inlen | 86 | (inlen |
87 | ? b64str[((to_uchar (in[1]) << 2) | 87 | ? b64str[((to_uchar (in[1]) << 2) |
88 | + (--inlen ? to_uchar (in[2]) >> 6 : 0)) | 88 | + (--inlen ? to_uchar (in[2]) >> 6 : 0)) |
89 | & 0x3f] | 89 | & 0x3f] |
90 | : '='); | 90 | : '='); |
91 | if (!--outlen) | 91 | if (!--outlen) |
92 | break; | 92 | break; |
93 | *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '='; | 93 | *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '='; |
94 | if (!--outlen) | 94 | if (!--outlen) |
95 | break; | 95 | break; |
96 | if (inlen) | 96 | if (inlen) |
97 | inlen--; | 97 | inlen--; |
98 | if (inlen) | 98 | if (inlen) |
99 | in += 3; | 99 | in += 3; |
100 | } | 100 | } |
101 | 101 | ||
102 | if (outlen) | 102 | if (outlen) |
@@ -153,71 +153,71 @@ base64_encode_alloc (const char *in, size_t inlen, char **out) | |||
153 | 153 | ||
154 | IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_" | 154 | IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_" |
155 | as the formal parameter rather than "x". */ | 155 | as the formal parameter rather than "x". */ |
156 | #define B64(_) \ | 156 | #define B64(_) \ |
157 | ((_) == 'A' ? 0 \ | 157 | ((_) == 'A' ? 0 \ |
158 | : (_) == 'B' ? 1 \ | 158 | : (_) == 'B' ? 1 \ |
159 | : (_) == 'C' ? 2 \ | 159 | : (_) == 'C' ? 2 \ |
160 | : (_) == 'D' ? 3 \ | 160 | : (_) == 'D' ? 3 \ |
161 | : (_) == 'E' ? 4 \ | 161 | : (_) == 'E' ? 4 \ |
162 | : (_) == 'F' ? 5 \ | 162 | : (_) == 'F' ? 5 \ |
163 | : (_) == 'G' ? 6 \ | 163 | : (_) == 'G' ? 6 \ |
164 | : (_) == 'H' ? 7 \ | 164 | : (_) == 'H' ? 7 \ |
165 | : (_) == 'I' ? 8 \ | 165 | : (_) == 'I' ? 8 \ |
166 | : (_) == 'J' ? 9 \ | 166 | : (_) == 'J' ? 9 \ |
167 | : (_) == 'K' ? 10 \ | 167 | : (_) == 'K' ? 10 \ |
168 | : (_) == 'L' ? 11 \ | 168 | : (_) == 'L' ? 11 \ |
169 | : (_) == 'M' ? 12 \ | 169 | : (_) == 'M' ? 12 \ |
170 | : (_) == 'N' ? 13 \ | 170 | : (_) == 'N' ? 13 \ |
171 | : (_) == 'O' ? 14 \ | 171 | : (_) == 'O' ? 14 \ |
172 | : (_) == 'P' ? 15 \ | 172 | : (_) == 'P' ? 15 \ |
173 | : (_) == 'Q' ? 16 \ | 173 | : (_) == 'Q' ? 16 \ |
174 | : (_) == 'R' ? 17 \ | 174 | : (_) == 'R' ? 17 \ |
175 | : (_) == 'S' ? 18 \ | 175 | : (_) == 'S' ? 18 \ |
176 | : (_) == 'T' ? 19 \ | 176 | : (_) == 'T' ? 19 \ |
177 | : (_) == 'U' ? 20 \ | 177 | : (_) == 'U' ? 20 \ |
178 | : (_) == 'V' ? 21 \ | 178 | : (_) == 'V' ? 21 \ |
179 | : (_) == 'W' ? 22 \ | 179 | : (_) == 'W' ? 22 \ |
180 | : (_) == 'X' ? 23 \ | 180 | : (_) == 'X' ? 23 \ |
181 | : (_) == 'Y' ? 24 \ | 181 | : (_) == 'Y' ? 24 \ |
182 | : (_) == 'Z' ? 25 \ | 182 | : (_) == 'Z' ? 25 \ |
183 | : (_) == 'a' ? 26 \ | 183 | : (_) == 'a' ? 26 \ |
184 | : (_) == 'b' ? 27 \ | 184 | : (_) == 'b' ? 27 \ |
185 | : (_) == 'c' ? 28 \ | 185 | : (_) == 'c' ? 28 \ |
186 | : (_) == 'd' ? 29 \ | 186 | : (_) == 'd' ? 29 \ |
187 | : (_) == 'e' ? 30 \ | 187 | : (_) == 'e' ? 30 \ |
188 | : (_) == 'f' ? 31 \ | 188 | : (_) == 'f' ? 31 \ |
189 | : (_) == 'g' ? 32 \ | 189 | : (_) == 'g' ? 32 \ |
190 | : (_) == 'h' ? 33 \ | 190 | : (_) == 'h' ? 33 \ |
191 | : (_) == 'i' ? 34 \ | 191 | : (_) == 'i' ? 34 \ |
192 | : (_) == 'j' ? 35 \ | 192 | : (_) == 'j' ? 35 \ |
193 | : (_) == 'k' ? 36 \ | 193 | : (_) == 'k' ? 36 \ |
194 | : (_) == 'l' ? 37 \ | 194 | : (_) == 'l' ? 37 \ |
195 | : (_) == 'm' ? 38 \ | 195 | : (_) == 'm' ? 38 \ |
196 | : (_) == 'n' ? 39 \ | 196 | : (_) == 'n' ? 39 \ |
197 | : (_) == 'o' ? 40 \ | 197 | : (_) == 'o' ? 40 \ |
198 | : (_) == 'p' ? 41 \ | 198 | : (_) == 'p' ? 41 \ |
199 | : (_) == 'q' ? 42 \ | 199 | : (_) == 'q' ? 42 \ |
200 | : (_) == 'r' ? 43 \ | 200 | : (_) == 'r' ? 43 \ |
201 | : (_) == 's' ? 44 \ | 201 | : (_) == 's' ? 44 \ |
202 | : (_) == 't' ? 45 \ | 202 | : (_) == 't' ? 45 \ |
203 | : (_) == 'u' ? 46 \ | 203 | : (_) == 'u' ? 46 \ |
204 | : (_) == 'v' ? 47 \ | 204 | : (_) == 'v' ? 47 \ |
205 | : (_) == 'w' ? 48 \ | 205 | : (_) == 'w' ? 48 \ |
206 | : (_) == 'x' ? 49 \ | 206 | : (_) == 'x' ? 49 \ |
207 | : (_) == 'y' ? 50 \ | 207 | : (_) == 'y' ? 50 \ |
208 | : (_) == 'z' ? 51 \ | 208 | : (_) == 'z' ? 51 \ |
209 | : (_) == '0' ? 52 \ | 209 | : (_) == '0' ? 52 \ |
210 | : (_) == '1' ? 53 \ | 210 | : (_) == '1' ? 53 \ |
211 | : (_) == '2' ? 54 \ | 211 | : (_) == '2' ? 54 \ |
212 | : (_) == '3' ? 55 \ | 212 | : (_) == '3' ? 55 \ |
213 | : (_) == '4' ? 56 \ | 213 | : (_) == '4' ? 56 \ |
214 | : (_) == '5' ? 57 \ | 214 | : (_) == '5' ? 57 \ |
215 | : (_) == '6' ? 58 \ | 215 | : (_) == '6' ? 58 \ |
216 | : (_) == '7' ? 59 \ | 216 | : (_) == '7' ? 59 \ |
217 | : (_) == '8' ? 60 \ | 217 | : (_) == '8' ? 60 \ |
218 | : (_) == '9' ? 61 \ | 218 | : (_) == '9' ? 61 \ |
219 | : (_) == '+' ? 62 \ | 219 | : (_) == '+' ? 62 \ |
220 | : (_) == '/' ? 63 \ | 220 | : (_) == '/' ? 63 \ |
221 | : -1) | 221 | : -1) |
222 | 222 | ||
223 | static const signed char b64[0x100] = { | 223 | static const signed char b64[0x100] = { |
@@ -328,12 +328,12 @@ get_4 (struct base64_decode_context *ctx, | |||
328 | { | 328 | { |
329 | char const *t = *in; | 329 | char const *t = *in; |
330 | if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL) | 330 | if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL) |
331 | { | 331 | { |
332 | /* This is the common case: no newline. */ | 332 | /* This is the common case: no newline. */ |
333 | *in += 4; | 333 | *in += 4; |
334 | *n_non_newline = 4; | 334 | *n_non_newline = 4; |
335 | return (char *) t; | 335 | return (char *) t; |
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||
339 | { | 339 | { |
@@ -341,13 +341,13 @@ get_4 (struct base64_decode_context *ctx, | |||
341 | char const *p = *in; | 341 | char const *p = *in; |
342 | while (p < in_end) | 342 | while (p < in_end) |
343 | { | 343 | { |
344 | char c = *p++; | 344 | char c = *p++; |
345 | if (c != '\n') | 345 | if (c != '\n') |
346 | { | 346 | { |
347 | ctx->buf[ctx->i++] = c; | 347 | ctx->buf[ctx->i++] = c; |
348 | if (ctx->i == 4) | 348 | if (ctx->i == 4) |
349 | break; | 349 | break; |
350 | } | 350 | } |
351 | } | 351 | } |
352 | 352 | ||
353 | *in = p; | 353 | *in = p; |
@@ -356,12 +356,12 @@ get_4 (struct base64_decode_context *ctx, | |||
356 | } | 356 | } |
357 | } | 357 | } |
358 | 358 | ||
359 | #define return_false \ | 359 | #define return_false \ |
360 | do \ | 360 | do \ |
361 | { \ | 361 | { \ |
362 | *outp = out; \ | 362 | *outp = out; \ |
363 | return false; \ | 363 | return false; \ |
364 | } \ | 364 | } \ |
365 | while (false) | 365 | while (false) |
366 | 366 | ||
367 | /* Decode up to four bytes of base64-encoded data, IN, of length INLEN | 367 | /* Decode up to four bytes of base64-encoded data, IN, of length INLEN |
@@ -372,7 +372,7 @@ get_4 (struct base64_decode_context *ctx, | |||
372 | *OUTLEN to reflect the number of bytes remaining in *OUT. */ | 372 | *OUTLEN to reflect the number of bytes remaining in *OUT. */ |
373 | static inline bool | 373 | static inline bool |
374 | decode_4 (char const *restrict in, size_t inlen, | 374 | decode_4 (char const *restrict in, size_t inlen, |
375 | char *restrict *outp, size_t *outleft) | 375 | char *restrict *outp, size_t *outleft) |
376 | { | 376 | { |
377 | char *out = *outp; | 377 | char *out = *outp; |
378 | if (inlen < 2) | 378 | if (inlen < 2) |
@@ -384,7 +384,7 @@ decode_4 (char const *restrict in, size_t inlen, | |||
384 | if (*outleft) | 384 | if (*outleft) |
385 | { | 385 | { |
386 | *out++ = ((b64[to_uchar (in[0])] << 2) | 386 | *out++ = ((b64[to_uchar (in[0])] << 2) |
387 | | (b64[to_uchar (in[1])] >> 4)); | 387 | | (b64[to_uchar (in[1])] >> 4)); |
388 | --*outleft; | 388 | --*outleft; |
389 | } | 389 | } |
390 | 390 | ||
@@ -394,43 +394,43 @@ decode_4 (char const *restrict in, size_t inlen, | |||
394 | if (in[2] == '=') | 394 | if (in[2] == '=') |
395 | { | 395 | { |
396 | if (inlen != 4) | 396 | if (inlen != 4) |
397 | return_false; | 397 | return_false; |
398 | 398 | ||
399 | if (in[3] != '=') | 399 | if (in[3] != '=') |
400 | return_false; | 400 | return_false; |
401 | } | 401 | } |
402 | else | 402 | else |
403 | { | 403 | { |
404 | if (!isbase64 (in[2])) | 404 | if (!isbase64 (in[2])) |
405 | return_false; | 405 | return_false; |
406 | 406 | ||
407 | if (*outleft) | 407 | if (*outleft) |
408 | { | 408 | { |
409 | *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0) | 409 | *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0) |
410 | | (b64[to_uchar (in[2])] >> 2)); | 410 | | (b64[to_uchar (in[2])] >> 2)); |
411 | --*outleft; | 411 | --*outleft; |
412 | } | 412 | } |
413 | 413 | ||
414 | if (inlen == 3) | 414 | if (inlen == 3) |
415 | return_false; | 415 | return_false; |
416 | 416 | ||
417 | if (in[3] == '=') | 417 | if (in[3] == '=') |
418 | { | 418 | { |
419 | if (inlen != 4) | 419 | if (inlen != 4) |
420 | return_false; | 420 | return_false; |
421 | } | 421 | } |
422 | else | 422 | else |
423 | { | 423 | { |
424 | if (!isbase64 (in[3])) | 424 | if (!isbase64 (in[3])) |
425 | return_false; | 425 | return_false; |
426 | 426 | ||
427 | if (*outleft) | 427 | if (*outleft) |
428 | { | 428 | { |
429 | *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0) | 429 | *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0) |
430 | | b64[to_uchar (in[3])]); | 430 | | b64[to_uchar (in[3])]); |
431 | --*outleft; | 431 | --*outleft; |
432 | } | 432 | } |
433 | } | 433 | } |
434 | } | 434 | } |
435 | 435 | ||
436 | *outp = out; | 436 | *outp = out; |
@@ -457,8 +457,8 @@ decode_4 (char const *restrict in, size_t inlen, | |||
457 | 457 | ||
458 | bool | 458 | bool |
459 | base64_decode_ctx (struct base64_decode_context *ctx, | 459 | base64_decode_ctx (struct base64_decode_context *ctx, |
460 | const char *restrict in, size_t inlen, | 460 | const char *restrict in, size_t inlen, |
461 | char *restrict out, size_t *outlen) | 461 | char *restrict out, size_t *outlen) |
462 | { | 462 | { |
463 | size_t outleft = *outlen; | 463 | size_t outleft = *outlen; |
464 | bool ignore_newlines = ctx != NULL; | 464 | bool ignore_newlines = ctx != NULL; |
@@ -476,57 +476,57 @@ base64_decode_ctx (struct base64_decode_context *ctx, | |||
476 | { | 476 | { |
477 | size_t outleft_save = outleft; | 477 | size_t outleft_save = outleft; |
478 | if (ctx_i == 0 && !flush_ctx) | 478 | if (ctx_i == 0 && !flush_ctx) |
479 | { | 479 | { |
480 | while (true) | 480 | while (true) |
481 | { | 481 | { |
482 | /* Save a copy of outleft, in case we need to re-parse this | 482 | /* Save a copy of outleft, in case we need to re-parse this |
483 | block of four bytes. */ | 483 | block of four bytes. */ |
484 | outleft_save = outleft; | 484 | outleft_save = outleft; |
485 | if (!decode_4 (in, inlen, &out, &outleft)) | 485 | if (!decode_4 (in, inlen, &out, &outleft)) |
486 | break; | 486 | break; |
487 | 487 | ||
488 | in += 4; | 488 | in += 4; |
489 | inlen -= 4; | 489 | inlen -= 4; |
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
493 | if (inlen == 0 && !flush_ctx) | 493 | if (inlen == 0 && !flush_ctx) |
494 | break; | 494 | break; |
495 | 495 | ||
496 | /* Handle the common case of 72-byte wrapped lines. | 496 | /* Handle the common case of 72-byte wrapped lines. |
497 | This also handles any other multiple-of-4-byte wrapping. */ | 497 | This also handles any other multiple-of-4-byte wrapping. */ |
498 | if (inlen && *in == '\n' && ignore_newlines) | 498 | if (inlen && *in == '\n' && ignore_newlines) |
499 | { | 499 | { |
500 | ++in; | 500 | ++in; |
501 | --inlen; | 501 | --inlen; |
502 | continue; | 502 | continue; |
503 | } | 503 | } |
504 | 504 | ||
505 | /* Restore OUT and OUTLEFT. */ | 505 | /* Restore OUT and OUTLEFT. */ |
506 | out -= outleft_save - outleft; | 506 | out -= outleft_save - outleft; |
507 | outleft = outleft_save; | 507 | outleft = outleft_save; |
508 | 508 | ||
509 | { | 509 | { |
510 | char const *in_end = in + inlen; | 510 | char const *in_end = in + inlen; |
511 | char const *non_nl; | 511 | char const *non_nl; |
512 | 512 | ||
513 | if (ignore_newlines) | 513 | if (ignore_newlines) |
514 | non_nl = get_4 (ctx, &in, in_end, &inlen); | 514 | non_nl = get_4 (ctx, &in, in_end, &inlen); |
515 | else | 515 | else |
516 | non_nl = in; /* Might have nl in this case. */ | 516 | non_nl = in; /* Might have nl in this case. */ |
517 | 517 | ||
518 | /* If the input is empty or consists solely of newlines (0 non-newlines), | 518 | /* If the input is empty or consists solely of newlines (0 non-newlines), |
519 | then we're done. Likewise if there are fewer than 4 bytes when not | 519 | then we're done. Likewise if there are fewer than 4 bytes when not |
520 | flushing context and not treating newlines as garbage. */ | 520 | flushing context and not treating newlines as garbage. */ |
521 | if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines)) | 521 | if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines)) |
522 | { | 522 | { |
523 | inlen = 0; | 523 | inlen = 0; |
524 | break; | 524 | break; |
525 | } | 525 | } |
526 | if (!decode_4 (non_nl, inlen, &out, &outleft)) | 526 | if (!decode_4 (non_nl, inlen, &out, &outleft)) |
527 | break; | 527 | break; |
528 | 528 | ||
529 | inlen = in_end - in; | 529 | inlen = in_end - in; |
530 | } | 530 | } |
531 | } | 531 | } |
532 | 532 | ||
@@ -548,8 +548,8 @@ base64_decode_ctx (struct base64_decode_context *ctx, | |||
548 | undefined. */ | 548 | undefined. */ |
549 | bool | 549 | bool |
550 | base64_decode_alloc_ctx (struct base64_decode_context *ctx, | 550 | base64_decode_alloc_ctx (struct base64_decode_context *ctx, |
551 | const char *in, size_t inlen, char **out, | 551 | const char *in, size_t inlen, char **out, |
552 | size_t *outlen) | 552 | size_t *outlen) |
553 | { | 553 | { |
554 | /* This may allocate a few bytes too many, depending on input, | 554 | /* This may allocate a few bytes too many, depending on input, |
555 | but it's not worth the extra CPU time to compute the exact size. | 555 | but it's not worth the extra CPU time to compute the exact size. |