diff options
Diffstat (limited to 'gl/base64.c')
-rw-r--r-- | gl/base64.c | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/gl/base64.c b/gl/base64.c index 95b669a..c8b3b76 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-2001, 2004-2006, 2009-2023 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2001, 2004-2006, 2009-2024 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
@@ -42,6 +42,7 @@ | |||
42 | #include <config.h> | 42 | #include <config.h> |
43 | 43 | ||
44 | /* Get prototype. */ | 44 | /* Get prototype. */ |
45 | #define BASE64_INLINE _GL_EXTERN_INLINE | ||
45 | #include "base64.h" | 46 | #include "base64.h" |
46 | 47 | ||
47 | /* Get imalloc. */ | 48 | /* Get imalloc. */ |
@@ -49,9 +50,6 @@ | |||
49 | 50 | ||
50 | #include <intprops.h> | 51 | #include <intprops.h> |
51 | 52 | ||
52 | /* Get UCHAR_MAX. */ | ||
53 | #include <limits.h> | ||
54 | |||
55 | #include <string.h> | 53 | #include <string.h> |
56 | 54 | ||
57 | /* Convert 'char' to 'unsigned char' without casting. */ | 55 | /* Convert 'char' to 'unsigned char' without casting. */ |
@@ -242,7 +240,7 @@ base64_encode_alloc (const char *in, idx_t inlen, char **out) | |||
242 | : (_) == '/' ? 63 \ | 240 | : (_) == '/' ? 63 \ |
243 | : -1) | 241 | : -1) |
244 | 242 | ||
245 | static const signed char b64[0x100] = { | 243 | signed char const base64_to_int[256] = { |
246 | B64 (0), B64 (1), B64 (2), B64 (3), | 244 | B64 (0), B64 (1), B64 (2), B64 (3), |
247 | B64 (4), B64 (5), B64 (6), B64 (7), | 245 | B64 (4), B64 (5), B64 (6), B64 (7), |
248 | B64 (8), B64 (9), B64 (10), B64 (11), | 246 | B64 (8), B64 (9), B64 (10), B64 (11), |
@@ -309,28 +307,6 @@ static const signed char b64[0x100] = { | |||
309 | B64 (252), B64 (253), B64 (254), B64 (255) | 307 | B64 (252), B64 (253), B64 (254), B64 (255) |
310 | }; | 308 | }; |
311 | 309 | ||
312 | #if UCHAR_MAX == 255 | ||
313 | # define uchar_in_range(c) true | ||
314 | #else | ||
315 | # define uchar_in_range(c) ((c) <= 255) | ||
316 | #endif | ||
317 | |||
318 | /* Return true if CH is a character from the Base64 alphabet, and | ||
319 | false otherwise. Note that '=' is padding and not considered to be | ||
320 | part of the alphabet. */ | ||
321 | bool | ||
322 | isbase64 (char ch) | ||
323 | { | ||
324 | return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)]; | ||
325 | } | ||
326 | |||
327 | /* Initialize decode-context buffer, CTX. */ | ||
328 | void | ||
329 | base64_decode_ctx_init (struct base64_decode_context *ctx) | ||
330 | { | ||
331 | ctx->i = 0; | ||
332 | } | ||
333 | |||
334 | /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and | 310 | /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and |
335 | none of those four is a newline, then return *IN. Otherwise, copy up to | 311 | none of those four is a newline, then return *IN. Otherwise, copy up to |
336 | 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at | 312 | 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at |
@@ -405,8 +381,8 @@ decode_4 (char const *restrict in, idx_t inlen, | |||
405 | 381 | ||
406 | if (*outleft) | 382 | if (*outleft) |
407 | { | 383 | { |
408 | *out++ = ((b64[to_uchar (in[0])] << 2) | 384 | *out++ = ((base64_to_int[to_uchar (in[0])] << 2) |
409 | | (b64[to_uchar (in[1])] >> 4)); | 385 | | (base64_to_int[to_uchar (in[1])] >> 4)); |
410 | --*outleft; | 386 | --*outleft; |
411 | } | 387 | } |
412 | 388 | ||
@@ -420,6 +396,10 @@ decode_4 (char const *restrict in, idx_t inlen, | |||
420 | 396 | ||
421 | if (in[3] != '=') | 397 | if (in[3] != '=') |
422 | return_false; | 398 | return_false; |
399 | |||
400 | /* Reject non-canonical encodings. */ | ||
401 | if (base64_to_int[to_uchar (in[1])] & 0x0f) | ||
402 | return_false; | ||
423 | } | 403 | } |
424 | else | 404 | else |
425 | { | 405 | { |
@@ -428,8 +408,8 @@ decode_4 (char const *restrict in, idx_t inlen, | |||
428 | 408 | ||
429 | if (*outleft) | 409 | if (*outleft) |
430 | { | 410 | { |
431 | *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0) | 411 | *out++ = (((base64_to_int[to_uchar (in[1])] << 4) & 0xf0) |
432 | | (b64[to_uchar (in[2])] >> 2)); | 412 | | (base64_to_int[to_uchar (in[2])] >> 2)); |
433 | --*outleft; | 413 | --*outleft; |
434 | } | 414 | } |
435 | 415 | ||
@@ -440,6 +420,10 @@ decode_4 (char const *restrict in, idx_t inlen, | |||
440 | { | 420 | { |
441 | if (inlen != 4) | 421 | if (inlen != 4) |
442 | return_false; | 422 | return_false; |
423 | |||
424 | /* Reject non-canonical encodings. */ | ||
425 | if (base64_to_int[to_uchar (in[2])] & 0x03) | ||
426 | return_false; | ||
443 | } | 427 | } |
444 | else | 428 | else |
445 | { | 429 | { |
@@ -448,8 +432,8 @@ decode_4 (char const *restrict in, idx_t inlen, | |||
448 | 432 | ||
449 | if (*outleft) | 433 | if (*outleft) |
450 | { | 434 | { |
451 | *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0) | 435 | *out++ = (((base64_to_int[to_uchar (in[2])] << 6) & 0xc0) |
452 | | b64[to_uchar (in[3])]); | 436 | | base64_to_int[to_uchar (in[3])]); |
453 | --*outleft; | 437 | --*outleft; |
454 | } | 438 | } |
455 | } | 439 | } |