1 | #include <glib.h> |
2 | #include <string.h> |
3 | #include <stdlib.h> |
4 | |
5 | #define DATA_SIZE 1024 |
6 | #define BLOCK_SIZE 32 |
7 | #define NUM_BLOCKS 32 |
8 | static guchar data[DATA_SIZE]; |
9 | |
10 | static void |
11 | test_incremental (gboolean line_break, |
12 | gsize length) |
13 | { |
14 | char *p; |
15 | gsize len, decoded_len, max, input_len, block_size; |
16 | int state, save; |
17 | guint decoder_save; |
18 | char *text; |
19 | guchar *data2; |
20 | |
21 | data2 = g_malloc (n_bytes: length); |
22 | text = g_malloc (n_bytes: length * 4); |
23 | |
24 | len = 0; |
25 | state = 0; |
26 | save = 0; |
27 | input_len = 0; |
28 | while (input_len < length) |
29 | { |
30 | block_size = MIN (BLOCK_SIZE, length - input_len); |
31 | len += g_base64_encode_step (in: data + input_len, len: block_size, |
32 | break_lines: line_break, out: text + len, state: &state, save: &save); |
33 | input_len += block_size; |
34 | } |
35 | len += g_base64_encode_close (break_lines: line_break, out: text + len, state: &state, save: &save); |
36 | |
37 | if (line_break) |
38 | max = length * 4 / 3 + length * 4 / (3 * 72) + 7; |
39 | else |
40 | max = length * 4 / 3 + 6; |
41 | |
42 | /* Check encoded length */ |
43 | g_assert_cmpint (len, <=, max); |
44 | |
45 | decoded_len = 0; |
46 | state = 0; |
47 | decoder_save = 0; |
48 | p = text; |
49 | while (len > 0) |
50 | { |
51 | int chunk_len = MIN (BLOCK_SIZE, len); |
52 | decoded_len += g_base64_decode_step (in: p, |
53 | len: chunk_len, |
54 | out: data2 + decoded_len, |
55 | state: &state, save: &decoder_save); |
56 | p += chunk_len; |
57 | len -= chunk_len; |
58 | } |
59 | |
60 | g_assert_cmpmem (data, length, data2, decoded_len); |
61 | |
62 | g_free (mem: text); |
63 | g_free (mem: data2); |
64 | } |
65 | |
66 | static void |
67 | test_incremental_break (gconstpointer d) |
68 | { |
69 | gint length = GPOINTER_TO_INT (d); |
70 | |
71 | test_incremental (TRUE, length); |
72 | } |
73 | |
74 | static void |
75 | test_incremental_nobreak (gconstpointer d) |
76 | { |
77 | gint length = GPOINTER_TO_INT (d); |
78 | |
79 | test_incremental (FALSE, length); |
80 | } |
81 | |
82 | static void |
83 | test_full (gconstpointer d) |
84 | { |
85 | gint length = GPOINTER_TO_INT (d); |
86 | char *text; |
87 | guchar *data2; |
88 | gsize len; |
89 | |
90 | text = g_base64_encode (data, len: length); |
91 | data2 = g_base64_decode (text, out_len: &len); |
92 | g_free (mem: text); |
93 | |
94 | g_assert_cmpmem (data, length, data2, len); |
95 | |
96 | g_free (mem: data2); |
97 | } |
98 | |
99 | struct MyRawData |
100 | { |
101 | gint length; /* of data */ |
102 | guchar data[DATA_SIZE]; |
103 | }; |
104 | |
105 | /* 100 pre-encoded string from data[] buffer. Data length from 1..100 |
106 | */ |
107 | static const char *ok_100_encode_strs[] = { |
108 | "AA==" , |
109 | "AAE=" , |
110 | "AAEC" , |
111 | "AAECAw==" , |
112 | "AAECAwQ=" , |
113 | "AAECAwQF" , |
114 | "AAECAwQFBg==" , |
115 | "AAECAwQFBgc=" , |
116 | "AAECAwQFBgcI" , |
117 | "AAECAwQFBgcICQ==" , |
118 | "AAECAwQFBgcICQo=" , |
119 | "AAECAwQFBgcICQoL" , |
120 | "AAECAwQFBgcICQoLDA==" , |
121 | "AAECAwQFBgcICQoLDA0=" , |
122 | "AAECAwQFBgcICQoLDA0O" , |
123 | "AAECAwQFBgcICQoLDA0ODw==" , |
124 | "AAECAwQFBgcICQoLDA0ODxA=" , |
125 | "AAECAwQFBgcICQoLDA0ODxAR" , |
126 | "AAECAwQFBgcICQoLDA0ODxAREg==" , |
127 | "AAECAwQFBgcICQoLDA0ODxAREhM=" , |
128 | "AAECAwQFBgcICQoLDA0ODxAREhMU" , |
129 | "AAECAwQFBgcICQoLDA0ODxAREhMUFQ==" , |
130 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRY=" , |
131 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYX" , |
132 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA==" , |
133 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk=" , |
134 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka" , |
135 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw==" , |
136 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw=" , |
137 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd" , |
138 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg==" , |
139 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=" , |
140 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g" , |
141 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gIQ==" , |
142 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISI=" , |
143 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj" , |
144 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJA==" , |
145 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCU=" , |
146 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUm" , |
147 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJw==" , |
148 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJyg=" , |
149 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygp" , |
150 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKg==" , |
151 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKis=" , |
152 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss" , |
153 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLQ==" , |
154 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4=" , |
155 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v" , |
156 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMA==" , |
157 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDE=" , |
158 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEy" , |
159 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMw==" , |
160 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ=" , |
161 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1" , |
162 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Ng==" , |
163 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc=" , |
164 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4" , |
165 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OQ==" , |
166 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo=" , |
167 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7" , |
168 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PA==" , |
169 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0=" , |
170 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+" , |
171 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==" , |
172 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0A=" , |
173 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BB" , |
174 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQg==" , |
175 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkM=" , |
176 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNE" , |
177 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERQ==" , |
178 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUY=" , |
179 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH" , |
180 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSA==" , |
181 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSEk=" , |
182 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElK" , |
183 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKSw==" , |
184 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0w=" , |
185 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xN" , |
186 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTg==" , |
187 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk8=" , |
188 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9Q" , |
189 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUQ==" , |
190 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVI=" , |
191 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJT" , |
192 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVA==" , |
193 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFU=" , |
194 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVW" , |
195 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWVw==" , |
196 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1g=" , |
197 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ" , |
198 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==" , |
199 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWls=" , |
200 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltc" , |
201 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXQ==" , |
202 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV4=" , |
203 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f" , |
204 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYA==" , |
205 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGE=" , |
206 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFi" , |
207 | "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiYw==" , |
208 | NULL |
209 | }; |
210 | |
211 | static void |
212 | generate_databuffer_for_base64 (struct MyRawData *p) |
213 | { |
214 | int i; |
215 | for (i = 0; i < DATA_SIZE; i++) |
216 | p->data[i] = i; |
217 | } |
218 | |
219 | static void |
220 | test_base64_encode (void) |
221 | { |
222 | int i; |
223 | gint length = 1; |
224 | char *text; |
225 | struct MyRawData myraw; |
226 | |
227 | generate_databuffer_for_base64 (p: &myraw); |
228 | |
229 | for (i = 0; ok_100_encode_strs[i]; i++) |
230 | { |
231 | length = i + 1; |
232 | text = g_base64_encode (data: myraw.data, len: length); |
233 | g_assert_cmpstr (text, ==, ok_100_encode_strs[i]); |
234 | /* printf ("\"%s\",\n",text); */ |
235 | g_free (mem: text); |
236 | } |
237 | } |
238 | |
239 | /* Test that incremental and all-in-one encoding of strings of a length which |
240 | * is not a multiple of 3 bytes behave the same, as the state carried over |
241 | * between g_base64_encode_step() calls varies depending on how the input is |
242 | * split up. This is like the test_base64_decode_smallblock() test, but for |
243 | * encoding. */ |
244 | static void |
245 | test_base64_encode_incremental_small_block (gconstpointer block_size_p) |
246 | { |
247 | gsize i; |
248 | struct MyRawData myraw; |
249 | |
250 | g_test_bug (bug_uri_snippet: "780066" ); |
251 | |
252 | generate_databuffer_for_base64 (p: &myraw); |
253 | |
254 | for (i = 0; ok_100_encode_strs[i] != NULL; i++) |
255 | { |
256 | const guint block_size = GPOINTER_TO_UINT (block_size_p); |
257 | gchar *encoded_complete = NULL; |
258 | gchar encoded_stepped[1024]; |
259 | gint state = 0, save = 0; |
260 | gsize len_written, len_read, len_to_read, input_length; |
261 | |
262 | input_length = i + 1; |
263 | |
264 | /* Do it all at once. */ |
265 | encoded_complete = g_base64_encode (data: myraw.data, len: input_length); |
266 | |
267 | /* Split the data up so some number of bits remain after each step. */ |
268 | for (len_written = 0, len_read = 0; len_read < input_length; len_read += len_to_read) |
269 | { |
270 | len_to_read = MIN (block_size, input_length - len_read); |
271 | len_written += g_base64_encode_step (in: myraw.data + len_read, len: len_to_read, |
272 | FALSE, |
273 | out: encoded_stepped + len_written, |
274 | state: &state, save: &save); |
275 | } |
276 | |
277 | len_written += g_base64_encode_close (FALSE, out: encoded_stepped + len_written, |
278 | state: &state, save: &save); |
279 | g_assert_cmpuint (len_written, <, G_N_ELEMENTS (encoded_stepped)); |
280 | |
281 | /* Nul-terminate to make string comparison easier. */ |
282 | encoded_stepped[len_written] = '\0'; |
283 | |
284 | /* Compare results. They should be the same. */ |
285 | g_assert_cmpstr (encoded_complete, ==, ok_100_encode_strs[i]); |
286 | g_assert_cmpstr (encoded_stepped, ==, encoded_complete); |
287 | |
288 | g_free (mem: encoded_complete); |
289 | } |
290 | } |
291 | |
292 | static void |
293 | decode_and_compare (const gchar *datap, |
294 | const struct MyRawData *p) |
295 | { |
296 | guchar *data2; |
297 | gsize len; |
298 | |
299 | data2 = g_base64_decode (text: datap, out_len: &len); |
300 | g_assert_cmpmem (p->data, p->length, data2, len); |
301 | g_free (mem: data2); |
302 | } |
303 | |
304 | static void |
305 | decode_inplace_and_compare (const gchar *datap, |
306 | const struct MyRawData *p) |
307 | { |
308 | gchar *data; |
309 | guchar *data2; |
310 | gsize len; |
311 | |
312 | data = g_strdup (str: datap); |
313 | data2 = g_base64_decode_inplace (text: data, out_len: &len); |
314 | g_assert_cmpmem (p->data, p->length, data2, len); |
315 | g_free (mem: data2); |
316 | } |
317 | |
318 | static void |
319 | test_base64_decode (void) |
320 | { |
321 | int i; |
322 | struct MyRawData myraw; |
323 | |
324 | generate_databuffer_for_base64 (p: &myraw); |
325 | |
326 | for (i = 0; ok_100_encode_strs[i]; i++) |
327 | { |
328 | myraw.length = i + 1; |
329 | decode_and_compare (datap: ok_100_encode_strs[i], p: &myraw); |
330 | } |
331 | } |
332 | |
333 | static void |
334 | test_base64_decode_inplace (void) |
335 | { |
336 | int i; |
337 | struct MyRawData myraw; |
338 | |
339 | generate_databuffer_for_base64 (p: &myraw); |
340 | |
341 | for (i = 0; ok_100_encode_strs[i]; i++) |
342 | { |
343 | myraw.length = i + 1; |
344 | decode_inplace_and_compare (datap: ok_100_encode_strs[i], p: &myraw); |
345 | } |
346 | } |
347 | |
348 | static void |
349 | test_base64_encode_decode (void) |
350 | { |
351 | int i; |
352 | char *text; |
353 | struct MyRawData myraw; |
354 | |
355 | generate_databuffer_for_base64 (p: &myraw); |
356 | |
357 | for (i = 0; i < DATA_SIZE; i++) |
358 | { |
359 | myraw.length = i + 1; |
360 | text = g_base64_encode (data: myraw.data, len: myraw.length); |
361 | |
362 | decode_and_compare (datap: text, p: &myraw); |
363 | |
364 | g_free (mem: text); |
365 | } |
366 | } |
367 | |
368 | static void |
369 | test_base64_decode_smallblock (gconstpointer blocksize_p) |
370 | { |
371 | const guint blocksize = GPOINTER_TO_UINT (blocksize_p); |
372 | guint i; |
373 | |
374 | for (i = 0; ok_100_encode_strs[i]; i++) |
375 | { |
376 | const char *str = ok_100_encode_strs[i]; |
377 | const char *p; |
378 | gsize len = strlen (s: str); |
379 | gint state = 0; |
380 | guint save = 0; |
381 | guchar *decoded; |
382 | gsize decoded_size = 0; |
383 | guchar *decoded_atonce; |
384 | gsize decoded_atonce_size = 0; |
385 | |
386 | decoded = g_malloc (n_bytes: len / 4 * 3 + 3); |
387 | |
388 | p = str; |
389 | while (len > 0) |
390 | { |
391 | int chunk_len = MIN (blocksize, len); |
392 | gsize size = g_base64_decode_step (in: p, len: chunk_len, |
393 | out: decoded + decoded_size, |
394 | state: &state, save: &save); |
395 | decoded_size += size; |
396 | len -= chunk_len; |
397 | p += chunk_len; |
398 | } |
399 | |
400 | decoded_atonce = g_base64_decode (text: str, out_len: &decoded_atonce_size); |
401 | |
402 | g_assert_cmpmem (decoded, decoded_size, decoded_atonce, decoded_atonce_size); |
403 | |
404 | g_free (mem: decoded); |
405 | g_free (mem: decoded_atonce); |
406 | } |
407 | } |
408 | |
409 | /* Test that calling g_base64_encode (NULL, 0) returns correct output. This is |
410 | * as per the first test vector in RFC 4648 §10. |
411 | * https://tools.ietf.org/html/rfc4648#section-10 */ |
412 | static void |
413 | test_base64_encode_empty (void) |
414 | { |
415 | gchar *encoded = NULL; |
416 | |
417 | g_test_bug (bug_uri_snippet: "https://gitlab.gnome.org/GNOME/glib/issues/1698" ); |
418 | |
419 | encoded = g_base64_encode (NULL, len: 0); |
420 | g_assert_cmpstr (encoded, ==, "" ); |
421 | g_free (mem: encoded); |
422 | |
423 | encoded = g_base64_encode (data: (const guchar *) "" , len: 0); |
424 | g_assert_cmpstr (encoded, ==, "" ); |
425 | g_free (mem: encoded); |
426 | } |
427 | |
428 | /* Test that calling g_base64_decode ("", *) returns correct output. This is |
429 | * as per the first test vector in RFC 4648 §10. Note that calling |
430 | * g_base64_decode (NULL, *) is not allowed. |
431 | * https://tools.ietf.org/html/rfc4648#section-10 */ |
432 | static void |
433 | test_base64_decode_empty (void) |
434 | { |
435 | guchar *decoded = NULL; |
436 | gsize decoded_len; |
437 | |
438 | g_test_bug (bug_uri_snippet: "https://gitlab.gnome.org/GNOME/glib/issues/1698" ); |
439 | |
440 | decoded = g_base64_decode (text: "" , out_len: &decoded_len); |
441 | g_assert_cmpstr ((gchar *) decoded, ==, "" ); |
442 | g_assert_cmpuint (decoded_len, ==, 0); |
443 | g_free (mem: decoded); |
444 | } |
445 | |
446 | /* Check all the RFC 4648 test vectors for base 64 encoding from §10. |
447 | * https://tools.ietf.org/html/rfc4648#section-10 */ |
448 | static void |
449 | test_base64_encode_decode_rfc4648 (void) |
450 | { |
451 | const struct |
452 | { |
453 | const gchar *decoded; /* technically this should be a byte array, but all the test vectors are ASCII strings */ |
454 | const gchar *encoded; |
455 | } |
456 | vectors[] = |
457 | { |
458 | { "" , "" }, |
459 | { "f" , "Zg==" }, |
460 | { "fo" , "Zm8=" }, |
461 | { "foo" , "Zm9v" }, |
462 | { "foob" , "Zm9vYg==" }, |
463 | { "fooba" , "Zm9vYmE=" }, |
464 | { "foobar" , "Zm9vYmFy" }, |
465 | }; |
466 | gsize i; |
467 | |
468 | for (i = 0; i < G_N_ELEMENTS (vectors); i++) |
469 | { |
470 | gchar *encoded = NULL; |
471 | guchar *decoded = NULL; |
472 | gsize expected_decoded_len = strlen (s: vectors[i].decoded); |
473 | gsize decoded_len; |
474 | |
475 | g_test_message (format: "Vector %" G_GSIZE_FORMAT ": %s" , i, vectors[i].decoded); |
476 | |
477 | encoded = g_base64_encode (data: (const guchar *) vectors[i].decoded, len: expected_decoded_len); |
478 | g_assert_cmpstr (encoded, ==, vectors[i].encoded); |
479 | |
480 | decoded = g_base64_decode (text: encoded, out_len: &decoded_len); |
481 | g_assert_cmpstr ((gchar *) decoded, ==, vectors[i].decoded); |
482 | g_assert_cmpuint (decoded_len, ==, expected_decoded_len); |
483 | |
484 | g_free (mem: encoded); |
485 | g_free (mem: decoded); |
486 | } |
487 | } |
488 | |
489 | int |
490 | main (int argc, char *argv[]) |
491 | { |
492 | gint i; |
493 | |
494 | g_test_init (argc: &argc, argv: &argv, NULL); |
495 | g_test_bug_base (uri_pattern: "https://bugzilla.gnome.org/browse.cgi?product=" ); |
496 | |
497 | for (i = 0; i < DATA_SIZE; i++) |
498 | data[i] = (guchar)i; |
499 | |
500 | g_test_add_data_func (testpath: "/base64/full/1" , GINT_TO_POINTER (DATA_SIZE), test_func: test_full); |
501 | g_test_add_data_func (testpath: "/base64/full/2" , GINT_TO_POINTER (1), test_func: test_full); |
502 | g_test_add_data_func (testpath: "/base64/full/3" , GINT_TO_POINTER (2), test_func: test_full); |
503 | g_test_add_data_func (testpath: "/base64/full/4" , GINT_TO_POINTER (3), test_func: test_full); |
504 | |
505 | g_test_add_data_func (testpath: "/base64/encode/incremental/small-block/1" , GINT_TO_POINTER (1), test_func: test_base64_encode_incremental_small_block); |
506 | g_test_add_data_func (testpath: "/base64/encode/incremental/small-block/2" , GINT_TO_POINTER (2), test_func: test_base64_encode_incremental_small_block); |
507 | g_test_add_data_func (testpath: "/base64/encode/incremental/small-block/3" , GINT_TO_POINTER (3), test_func: test_base64_encode_incremental_small_block); |
508 | g_test_add_data_func (testpath: "/base64/encode/incremental/small-block/4" , GINT_TO_POINTER (4), test_func: test_base64_encode_incremental_small_block); |
509 | |
510 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/1" , GINT_TO_POINTER (DATA_SIZE), test_func: test_incremental_nobreak); |
511 | g_test_add_data_func (testpath: "/base64/incremental/break/1" , GINT_TO_POINTER (DATA_SIZE), test_func: test_incremental_break); |
512 | |
513 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/2" , GINT_TO_POINTER (DATA_SIZE - 1), test_func: test_incremental_nobreak); |
514 | g_test_add_data_func (testpath: "/base64/incremental/break/2" , GINT_TO_POINTER (DATA_SIZE - 1), test_func: test_incremental_break); |
515 | |
516 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/3" , GINT_TO_POINTER (DATA_SIZE - 2), test_func: test_incremental_nobreak); |
517 | g_test_add_data_func (testpath: "/base64/incremental/break/3" , GINT_TO_POINTER (DATA_SIZE - 2), test_func: test_incremental_break); |
518 | |
519 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/4-a" , GINT_TO_POINTER (1), test_func: test_incremental_nobreak); |
520 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/4-b" , GINT_TO_POINTER (2), test_func: test_incremental_nobreak); |
521 | g_test_add_data_func (testpath: "/base64/incremental/nobreak/4-c" , GINT_TO_POINTER (3), test_func: test_incremental_nobreak); |
522 | |
523 | g_test_add_func (testpath: "/base64/encode" , test_func: test_base64_encode); |
524 | g_test_add_func (testpath: "/base64/decode" , test_func: test_base64_decode); |
525 | g_test_add_func (testpath: "/base64/decode-inplace" , test_func: test_base64_decode_inplace); |
526 | g_test_add_func (testpath: "/base64/encode-decode" , test_func: test_base64_encode_decode); |
527 | |
528 | g_test_add_data_func (testpath: "/base64/incremental/smallblock/1" , GINT_TO_POINTER(1), |
529 | test_func: test_base64_decode_smallblock); |
530 | g_test_add_data_func (testpath: "/base64/incremental/smallblock/2" , GINT_TO_POINTER(2), |
531 | test_func: test_base64_decode_smallblock); |
532 | g_test_add_data_func (testpath: "/base64/incremental/smallblock/3" , GINT_TO_POINTER(3), |
533 | test_func: test_base64_decode_smallblock); |
534 | g_test_add_data_func (testpath: "/base64/incremental/smallblock/4" , GINT_TO_POINTER(4), |
535 | test_func: test_base64_decode_smallblock); |
536 | |
537 | g_test_add_func (testpath: "/base64/encode/empty" , test_func: test_base64_encode_empty); |
538 | g_test_add_func (testpath: "/base64/decode/empty" , test_func: test_base64_decode_empty); |
539 | |
540 | g_test_add_func (testpath: "/base64/encode-decode/rfc4648" , test_func: test_base64_encode_decode_rfc4648); |
541 | |
542 | return g_test_run (); |
543 | } |
544 | |