NeoMutt  2025-12-11-58-g09398d
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
base64.c File Reference

Conversion to/from base64 encoding. More...

#include "config.h"
#include "base64.h"
#include "buffer.h"
#include "memory.h"
#include "string2.h"
+ Include dependency graph for base64.c:

Go to the source code of this file.

Macros

#define BAD   -1
 

Functions

static size_t b64_encode (const char *in, size_t inlen, char *out, size_t outlen, const char *alpha)
 Convert raw bytes to NUL-terminated base64 string.
 
size_t mutt_b64_encode (const char *in, size_t inlen, char *out, size_t outlen)
 Convert raw bytes to a base64 string.
 
size_t mutt_b64_encode_urlsafe (const char *in, size_t inlen, char *out, size_t outlen)
 Convert raw bytes to a URL-safe base64 string.
 
int mutt_b64_decode (const char *in, char *out, size_t olen)
 Convert NUL-terminated base64 string to raw bytes.
 
size_t mutt_b64_buffer_encode (struct Buffer *buf, const char *in, size_t len)
 Convert raw bytes to NUL-terminated base64 string.
 
int mutt_b64_buffer_decode (struct Buffer *buf, const char *in)
 Convert NUL-terminated base64 string to raw bytes.
 

Variables

static const char B64Chars [64]
 Characters of the Base64 encoding.
 
static const char B64CharsUrlSafe [64]
 URL-Safe Characters of the Base64 encoding.
 
const int Index64 [128]
 Lookup table for Base64 encoding characters.
 

Detailed Description

Conversion to/from base64 encoding.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file base64.c.

Macro Definition Documentation

◆ BAD

#define BAD   -1

Definition at line 39 of file base64.c.

Function Documentation

◆ b64_encode()

static size_t b64_encode ( const char * in,
size_t inlen,
char * out,
size_t outlen,
const char * alpha )
static

Convert raw bytes to NUL-terminated base64 string.

Parameters
inInput buffer for the raw bytes
inlenLength of the input buffer
outOutput buffer for the base64 encoded string
outlenLength of the output buffer
alphaAlphabet to encode with
Return values
numLength of the string written to the output buffer

This function performs base64 encoding. The resulting string is guaranteed to be NUL-terminated. The number of characters up to the terminating NUL-byte is returned (equivalent to calling strlen() on the output buffer after this function returns).

Definition at line 101 of file base64.c.

103{
104 if (!in || !out)
105 return 0;
106
107 unsigned char *begin = (unsigned char *) out;
108 const unsigned char *inu = (const unsigned char *) in;
109
110 while ((inlen >= 3) && (outlen > 4))
111 {
112 *out++ = alpha[inu[0] >> 2];
113 *out++ = alpha[((inu[0] << 4) & 0x30) | (inu[1] >> 4)];
114 *out++ = alpha[((inu[1] << 2) & 0x3c) | (inu[2] >> 6)];
115 *out++ = alpha[inu[2] & 0x3f];
116 outlen -= 4;
117 inlen -= 3;
118 inu += 3;
119 }
120
121 /* clean up remainder */
122 if ((inlen > 0) && (outlen > 4))
123 {
124 unsigned char fragment;
125
126 *out++ = alpha[inu[0] >> 2];
127 fragment = (inu[0] << 4) & 0x30;
128 if (inlen > 1)
129 fragment |= inu[1] >> 4;
130 *out++ = alpha[fragment];
131 *out++ = (inlen < 2) ? '=' : alpha[(inu[1] << 2) & 0x3c];
132 *out++ = '=';
133 }
134 *out = '\0';
135 return out - (char *) begin;
136}
+ Here is the caller graph for this function:

◆ mutt_b64_encode()

size_t mutt_b64_encode ( const char * in,
size_t inlen,
char * out,
size_t outlen )

Convert raw bytes to a base64 string.

Parameters
inInput buffer for the raw bytes
inlenLength of the input buffer
outOutput buffer for the base64 encoded string
outlenLength of the output buffer
Return values
numLength of the string written to the output buffer
See also
b64_encode()

Definition at line 148 of file base64.c.

149{
150 return b64_encode(in, inlen, out, outlen, B64Chars);
151}
static size_t b64_encode(const char *in, size_t inlen, char *out, size_t outlen, const char *alpha)
Convert raw bytes to NUL-terminated base64 string.
Definition base64.c:101
static const char B64Chars[64]
Characters of the Base64 encoding.
Definition utf7.c:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_b64_encode_urlsafe()

size_t mutt_b64_encode_urlsafe ( const char * in,
size_t inlen,
char * out,
size_t outlen )

Convert raw bytes to a URL-safe base64 string.

Parameters
inInput buffer for the raw bytes
inlenLength of the input buffer
outOutput buffer for the base64 encoded string
outlenLength of the output buffer
Return values
numLength of the string written to the output buffer
See also
b64_encode()

Definition at line 163 of file base64.c.

164{
165 return b64_encode(in, inlen, out, outlen, B64CharsUrlSafe);
166}
static const char B64CharsUrlSafe[64]
URL-Safe Characters of the Base64 encoding.
Definition base64.c:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_b64_decode()

int mutt_b64_decode ( const char * in,
char * out,
size_t olen )

Convert NUL-terminated base64 string to raw bytes.

Parameters
inInput buffer for the NUL-terminated base64-encoded string
outOutput buffer for the raw bytes
olenLength of the output buffer
Return values
numSuccess, bytes written
-1Error

This function performs base64 decoding. The resulting buffer is NOT NUL-terminated. If the input buffer contains invalid base64 characters, this function returns -1.

Definition at line 180 of file base64.c.

181{
182 if (!in || !*in || !out)
183 return -1;
184
185 int len = 0;
186
187 for (; *in; in += 4)
188 {
189 const unsigned char digit1 = in[0];
190 if ((digit1 > 127) || (base64val(digit1) == BAD))
191 return -1;
192 const unsigned char digit2 = in[1];
193 if ((digit2 > 127) || (base64val(digit2) == BAD))
194 return -1;
195
196 /* The 3rd and 4th bytes can be terminating padding chars ('='). Some
197 * mailers don't properly terminate base64-encoded strings, so we allow for
198 * the input string to terminate without padding. */
199 const unsigned char digit3 = in[2] ? in[2] : '=';
200 if ((digit3 > 127) || ((digit3 != '=') && (base64val(digit3) == BAD)))
201 return -1;
202 const unsigned char digit4 = (digit3 == '=') ? '=' : in[3];
203 if ((digit4 > 127) || ((digit4 != '=') && (base64val(digit4) == BAD)))
204 return -1;
205
206 /* digits are already sanity-checked */
207 if (len == olen)
208 return len;
209 *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4);
210 len++;
211 if (digit3 != '=')
212 {
213 if (len == olen)
214 return len;
215 *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2);
216 len++;
217 if (digit4 != '=')
218 {
219 if (len == olen)
220 return len;
221 *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4);
222 len++;
223 }
224 }
225
226 /* did we reach the end? */
227 if (digit4 == '=')
228 {
229 break;
230 }
231 }
232
233 return len;
234}
#define BAD
Definition base64.c:39
#define base64val(ch)
Definition base64.h:32
+ Here is the caller graph for this function:

◆ mutt_b64_buffer_encode()

size_t mutt_b64_buffer_encode ( struct Buffer * buf,
const char * in,
size_t len )

Convert raw bytes to NUL-terminated base64 string.

Parameters
bufBuffer for the result
inInput buffer for the raw bytes
lenLength of the input buffer
Return values
numLength of the string written to the output buffer

Definition at line 243 of file base64.c.

244{
245 if (!buf)
246 return 0;
247
248 buf_alloc(buf, MAX((len * 2), 1024));
249 size_t num = mutt_b64_encode(in, len, buf->data, buf->dsize);
250 buf_fix_dptr(buf);
251 return num;
252}
size_t mutt_b64_encode(const char *in, size_t inlen, char *out, size_t outlen)
Convert raw bytes to a base64 string.
Definition base64.c:148
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:182
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition buffer.c:337
#define MAX(a, b)
Definition memory.h:36
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_b64_buffer_decode()

int mutt_b64_buffer_decode ( struct Buffer * buf,
const char * in )

Convert NUL-terminated base64 string to raw bytes.

Parameters
bufBuffer for the result
inInput buffer for the NUL-terminated base64-encoded string
Return values
numSuccess, bytes written
-1Error

Definition at line 261 of file base64.c.

262{
263 if (!buf)
264 return -1;
265
266 buf_alloc(buf, mutt_str_len(in));
267 int olen = mutt_b64_decode(in, buf->data, buf->dsize);
268 // mutt_b64_decode returns raw bytes, so don't terminate the buffer either
269 if (olen > 0)
270 buf_seek(buf, olen);
271 else
272 buf_seek(buf, 0);
273
274 return olen;
275}
int mutt_b64_decode(const char *in, char *out, size_t olen)
Convert NUL-terminated base64 string to raw bytes.
Definition base64.c:180
void buf_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition buffer.c:622
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ B64Chars

const char B64Chars[64]
static
Initial value:
= {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
}

Characters of the Base64 encoding.

Definition at line 44 of file base64.c.

44 {
45 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
46 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
47 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
48 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
49 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
50};

◆ B64CharsUrlSafe

const char B64CharsUrlSafe[64]
static
Initial value:
= {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
}

URL-Safe Characters of the Base64 encoding.

RFC4648 section 5 Base 64 Encoding with URL and Filename Safe Alphabet

Definition at line 57 of file base64.c.

57 {
58 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
59 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
60 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
61 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
62 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
63};

◆ Index64

const int Index64[128]
Initial value:
= {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
}

Lookup table for Base64 encoding characters.

Note
This is very similar to the table in imap/utf7.c

Encoding chars:

  • utf7 A-Za-z0-9+,
  • mime A-Za-z0-9+/

Definition at line 74 of file base64.c.

74 {
75 // clang-format off
76 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
77 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
78 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
79 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
80 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
81 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
82 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
83 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
84 // clang-format on
85};