diff options
Diffstat (limited to 'lib/base32.c')
-rw-r--r-- | lib/base32.c | 72 |
1 files changed, 33 insertions, 39 deletions
diff --git a/lib/base32.c b/lib/base32.c index 50f9d42..270c505 100644 --- a/lib/base32.c +++ b/lib/base32.c @@ -1,5 +1,5 @@ /* base32.c -- Encode binary data using printable characters. - Copyright (C) 1999-2001, 2004-2006, 2009-2023 Free Software Foundation, Inc. + Copyright (C) 1999-2001, 2004-2006, 2009-2024 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -40,6 +40,7 @@ #include <config.h> /* Get prototype. */ +#define BASE32_INLINE _GL_EXTERN_INLINE #include "base32.h" /* Get imalloc. */ @@ -47,9 +48,6 @@ #include <intprops.h> -/* Get UCHAR_MAX. */ -#include <limits.h> - #include <string.h> /* Convert 'char' to 'unsigned char' without casting. */ @@ -205,7 +203,7 @@ base32_encode_alloc (const char *in, idx_t inlen, char **out) : (_) == '7' ? 31 \ : -1) -static const signed char b32[0x100] = { +signed char const base32_to_int[256] = { B32 (0), B32 (1), B32 (2), B32 (3), B32 (4), B32 (5), B32 (6), B32 (7), B32 (8), B32 (9), B32 (10), B32 (11), @@ -272,28 +270,6 @@ static const signed char b32[0x100] = { B32 (252), B32 (253), B32 (254), B32 (255) }; -#if UCHAR_MAX == 255 -# define uchar_in_range(c) true -#else -# define uchar_in_range(c) ((c) <= 255) -#endif - -/* Return true if CH is a character from the Base32 alphabet, and - false otherwise. Note that '=' is padding and not considered to be - part of the alphabet. */ -bool -isbase32 (char ch) -{ - return uchar_in_range (to_uchar (ch)) && 0 <= b32[to_uchar (ch)]; -} - -/* Initialize decode-context buffer, CTX. */ -void -base32_decode_ctx_init (struct base32_decode_context *ctx) -{ - ctx->i = 0; -} - /* If CTX->i is 0 or 8, there are eight or more bytes in [*IN..IN_END), and none of those eight is a newline, then return *IN. Otherwise, copy up to 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at @@ -368,8 +344,8 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[0])] << 3) - | (b32[to_uchar (in[1])] >> 2)); + *out++ = ((base32_to_int[to_uchar (in[0])] << 3) + | (base32_to_int[to_uchar (in[1])] >> 2)); --*outleft; } @@ -378,6 +354,10 @@ decode_8 (char const *restrict in, idx_t inlen, if (in[3] != '=' || in[4] != '=' || in[5] != '=' || in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[1])] & 0x03) + return_false; } else { @@ -386,9 +366,9 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[1])] << 6) - | (b32[to_uchar (in[2])] << 1) - | (b32[to_uchar (in[3])] >> 4)); + *out++ = ((base32_to_int[to_uchar (in[1])] << 6) + | (base32_to_int[to_uchar (in[2])] << 1) + | (base32_to_int[to_uchar (in[3])] >> 4)); --*outleft; } @@ -396,6 +376,10 @@ decode_8 (char const *restrict in, idx_t inlen, { if (in[5] != '=' || in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[3])] & 0x0f) + return_false; } else { @@ -404,8 +388,8 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[3])] << 4) - | (b32[to_uchar (in[4])] >> 1)); + *out++ = ((base32_to_int[to_uchar (in[3])] << 4) + | (base32_to_int[to_uchar (in[4])] >> 1)); --*outleft; } @@ -413,6 +397,10 @@ decode_8 (char const *restrict in, idx_t inlen, { if (in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[4])] & 0x01) + return_false; } else { @@ -421,9 +409,9 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[4])] << 7) - | (b32[to_uchar (in[5])] << 2) - | (b32[to_uchar (in[6])] >> 3)); + *out++ = ((base32_to_int[to_uchar (in[4])] << 7) + | (base32_to_int[to_uchar (in[5])] << 2) + | (base32_to_int[to_uchar (in[6])] >> 3)); --*outleft; } @@ -434,11 +422,17 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[6])] << 5) - | (b32[to_uchar (in[7])])); + *out++ = ((base32_to_int[to_uchar (in[6])] << 5) + | (base32_to_int[to_uchar (in[7])])); --*outleft; } } + else + { + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[6])] & 0x07) + return_false; + } } } } |