summaryrefslogtreecommitdiffstats
path: root/gl/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/base64.c')
-rw-r--r--gl/base64.c338
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. */
68void 68void
69base64_encode (const char *restrict in, size_t inlen, 69base64_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
223static const signed char b64[0x100] = { 223static 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. */
373static inline bool 373static inline bool
374decode_4 (char const *restrict in, size_t inlen, 374decode_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
458bool 458bool
459base64_decode_ctx (struct base64_decode_context *ctx, 459base64_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. */
549bool 549bool
550base64_decode_alloc_ctx (struct base64_decode_context *ctx, 550base64_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.