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 95b669aa..c8b3b76b 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 | } |
