summaryrefslogtreecommitdiffstats
path: root/gl/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/base64.c')
-rw-r--r--gl/base64.c50
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
245static const signed char b64[0x100] = { 243signed 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. */
321bool
322isbase64 (char ch)
323{
324 return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
325}
326
327/* Initialize decode-context buffer, CTX. */
328void
329base64_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 }