summaryrefslogtreecommitdiffstats
path: root/lib/base32.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/base32.c')
-rw-r--r--lib/base32.c72
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;
+ }
}
}
}