File: modp_b64.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (159 lines) | stat: -rw-r--r-- 4,631 bytes parent folder | download | duplicates (11)
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */

/**
 * \file
 * <PRE>
 * High performance base64 encoder / decoder
 * Version 1.3 -- 17-Mar-2006
 *
 * Copyright &copy; 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
 * All rights reserved.
 *
 * http://modp.com/release/base64
 *
 * Released under bsd license.  See modp_b64.c for details.
 * </pre>
 *
 * The default implementation is the standard b64 encoding with padding.
 * It's easy to change this to use "URL safe" characters and to remove
 * padding.  See the modp_b64.c source code for details.
 *
 */

#ifndef MODP_B64
#define MODP_B64

#include <limits.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Encode a raw binary string into base 64.
 * src contains the bytes
 * len contains the number of bytes in the src
 * dest should be allocated by the caller to contain
 *   at least modp_b64_encode_len(len) bytes (see below)
 *   This will contain the (non-null terminated) b64 bytes.
 * returns length of the destination string.
 *
 * Example
 *
 * \code
 * char* src = ...;
 * int srclen = ...; //the length of number of bytes in src
 * char* dest = (char*) malloc(modp_b64_encode_len);
 * int len = modp_b64_encode_data(dest, src, sourcelen);
 * if (len == -1) {
 *   printf("Error\n");
 * } else {
 *   printf("b64 = %s\n", dest);
 * }
 * \endcode
 *
 */
size_t modp_b64_encode_data(char* dest, const char* str, size_t len);

/**
 * Same as modp_b64_encode_data, but additionally sets a null terminator at the
 * end of `dest` (i.e. at dest[output_size]).
 * Like modp_b64_encode_data, returns the length of the destination string (i.e.
 * not counting the null terminator).
 *
 * TODO(csharrison): Consider removing this once all callers migrate to
 * modp_b64_encode_data.
 */
size_t modp_b64_encode(char* dest, const char* str, size_t len);

/**
 * Decode a base64 encoded string
 *
 * src should contain exactly len bytes of b64 characters.
 *     if src contains -any- non-base characters (such as white
 *     space, -1 is returned.
 *
 * dest should be allocated by the caller to contain at least
 *    len * 3 / 4 bytes.
 *
 * Returns the length (strlen) of the output, or -1 if unable to
 * decode
 *
 * \code
 * char* src = ...;
 * int srclen = ...; // or if you don't know use strlen(src)
 * char* dest = (char*) malloc(modp_b64_decode_len(srclen));
 * int len = modp_b64_decode(dest, src, sourcelen);
 * if (len == -1) { error }
 * \endcode
 */
enum class ModpDecodePolicy {
  // src length must be divisible by 4, with a max of 2 pad chars.
  kStrict,

  // Matches the infra spec: https://infra.spec.whatwg.org/#forgiving-base64
  // _except_ for ignoring whitespace (Step 1).
  kForgiving,

  // src length % 4 must not equal 1, after stripping all pad chars.
  // Accepts any number of pad chars.
  kNoPaddingValidation,
};
size_t modp_b64_decode(
    char* dest,
    const char* src,
    size_t len,
    ModpDecodePolicy policy = ModpDecodePolicy::kStrict);

/**
 * The maximum input that can be passed into modp_b64_encode{_data}.
 * Lengths beyond this will overflow modp_b64_encode_len.
 *
 * This works because modp_b64_encode_len(A) computes:
 *     ceiling[max_len / 3] * 4 + 1
 *   = ceiling[floor[(SIZE_MAX-1)/4]*3 / 3] * 4 + 1
 *   = floor[(SIZE_MAX-1)/4] * 4 + 1
 *  <= SIZE_MAX-1 + 1
 *   = SIZE_MAX
 *
 * Note: technically modp_b64_encode_data can take one extra byte, but for
 * simplicity the bound is shared between the two functions.
 */
#define MODP_B64_MAX_INPUT_LEN ((SIZE_MAX - 1) / 4 * 3)

/**
 * Given a source string of length len, this returns the amount of
 * memory the destination string should have, for modp_b64_encode_data and
 * modp_b64_encode, respectively.
 *
 * remember, this is integer math
 * 3 bytes turn into 4 chars
 * ceiling[len / 3] * 4
 *
 *
 * WARNING: These expressions will overflow if the A is above
 * MODP_B64_MAX_INPUT_LEN. The caller must check this bound first.
 */
#define modp_b64_encode_data_len(A) ((A + 2) / 3 * 4)
#define modp_b64_encode_len(A) (modp_b64_encode_data_len(A) + 1)

/**
 * Given a base64 string of length len,
 *   this returns the amount of memory required for output string
 *  It maybe be more than the actual number of bytes written.
 * NOTE: remember this is integer math
 * this allocates a bit more memory than traditional versions of b64
 * decode  4 chars turn into 3 bytes
 * floor[len * 3/4] + 2
 */
#define modp_b64_decode_len(A) (A / 4 * 3 + 2)

#define MODP_B64_ERROR ((size_t)-1)

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* MODP_B64 */