Mercurial > trustbridge > nss-cmake-static
comparison nspr/lib/libc/src/base64.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
5 | |
6 #include "plbase64.h" | |
7 #include "prlog.h" /* For PR_NOT_REACHED */ | |
8 #include "prmem.h" /* for malloc / PR_MALLOC */ | |
9 | |
10 #include <string.h> /* for strlen */ | |
11 | |
12 static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
13 | |
14 static void | |
15 encode3to4 | |
16 ( | |
17 const unsigned char *src, | |
18 unsigned char *dest | |
19 ) | |
20 { | |
21 PRUint32 b32 = (PRUint32)0; | |
22 PRIntn i, j = 18; | |
23 | |
24 for( i = 0; i < 3; i++ ) | |
25 { | |
26 b32 <<= 8; | |
27 b32 |= (PRUint32)src[i]; | |
28 } | |
29 | |
30 for( i = 0; i < 4; i++ ) | |
31 { | |
32 dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ]; | |
33 j -= 6; | |
34 } | |
35 | |
36 return; | |
37 } | |
38 | |
39 static void | |
40 encode2to4 | |
41 ( | |
42 const unsigned char *src, | |
43 unsigned char *dest | |
44 ) | |
45 { | |
46 dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; | |
47 dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ]; | |
48 dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ]; | |
49 dest[3] = (unsigned char)'='; | |
50 return; | |
51 } | |
52 | |
53 static void | |
54 encode1to4 | |
55 ( | |
56 const unsigned char *src, | |
57 unsigned char *dest | |
58 ) | |
59 { | |
60 dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; | |
61 dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ]; | |
62 dest[2] = (unsigned char)'='; | |
63 dest[3] = (unsigned char)'='; | |
64 return; | |
65 } | |
66 | |
67 static void | |
68 encode | |
69 ( | |
70 const unsigned char *src, | |
71 PRUint32 srclen, | |
72 unsigned char *dest | |
73 ) | |
74 { | |
75 while( srclen >= 3 ) | |
76 { | |
77 encode3to4(src, dest); | |
78 src += 3; | |
79 dest += 4; | |
80 srclen -= 3; | |
81 } | |
82 | |
83 switch( srclen ) | |
84 { | |
85 case 2: | |
86 encode2to4(src, dest); | |
87 break; | |
88 case 1: | |
89 encode1to4(src, dest); | |
90 break; | |
91 case 0: | |
92 break; | |
93 default: | |
94 PR_NOT_REACHED("coding error"); | |
95 } | |
96 | |
97 return; | |
98 } | |
99 | |
100 /* | |
101 * PL_Base64Encode | |
102 * | |
103 * If the destination argument is NULL, a return buffer is | |
104 * allocated, and the data therein will be null-terminated. | |
105 * If the destination argument is not NULL, it is assumed to | |
106 * be of sufficient size, and the contents will not be null- | |
107 * terminated by this routine. | |
108 * | |
109 * Returns null if the allocation fails. | |
110 */ | |
111 | |
112 PR_IMPLEMENT(char *) | |
113 PL_Base64Encode | |
114 ( | |
115 const char *src, | |
116 PRUint32 srclen, | |
117 char *dest | |
118 ) | |
119 { | |
120 if( 0 == srclen ) | |
121 { | |
122 size_t len = strlen(src); | |
123 srclen = len; | |
124 /* Detect truncation. */ | |
125 if( srclen != len ) | |
126 { | |
127 return (char *)0; | |
128 } | |
129 } | |
130 | |
131 if( (char *)0 == dest ) | |
132 { | |
133 PRUint32 destlen; | |
134 /* Ensure all PRUint32 values stay within range. */ | |
135 if( srclen > (PR_UINT32_MAX/4) * 3 ) | |
136 { | |
137 return (char *)0; | |
138 } | |
139 destlen = ((srclen + 2)/3) * 4; | |
140 dest = (char *)PR_MALLOC(destlen + 1); | |
141 if( (char *)0 == dest ) | |
142 { | |
143 return (char *)0; | |
144 } | |
145 dest[ destlen ] = (char)0; /* null terminate */ | |
146 } | |
147 | |
148 encode((const unsigned char *)src, srclen, (unsigned char *)dest); | |
149 return dest; | |
150 } | |
151 | |
152 static PRInt32 | |
153 codetovalue | |
154 ( | |
155 unsigned char c | |
156 ) | |
157 { | |
158 if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) | |
159 { | |
160 return (PRInt32)(c - (unsigned char)'A'); | |
161 } | |
162 else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) | |
163 { | |
164 return ((PRInt32)(c - (unsigned char)'a') +26); | |
165 } | |
166 else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) | |
167 { | |
168 return ((PRInt32)(c - (unsigned char)'0') +52); | |
169 } | |
170 else if( (unsigned char)'+' == c ) | |
171 { | |
172 return (PRInt32)62; | |
173 } | |
174 else if( (unsigned char)'/' == c ) | |
175 { | |
176 return (PRInt32)63; | |
177 } | |
178 else | |
179 { | |
180 return -1; | |
181 } | |
182 } | |
183 | |
184 static PRStatus | |
185 decode4to3 | |
186 ( | |
187 const unsigned char *src, | |
188 unsigned char *dest | |
189 ) | |
190 { | |
191 PRUint32 b32 = (PRUint32)0; | |
192 PRInt32 bits; | |
193 PRIntn i; | |
194 | |
195 for( i = 0; i < 4; i++ ) | |
196 { | |
197 bits = codetovalue(src[i]); | |
198 if( bits < 0 ) | |
199 { | |
200 return PR_FAILURE; | |
201 } | |
202 | |
203 b32 <<= 6; | |
204 b32 |= bits; | |
205 } | |
206 | |
207 dest[0] = (unsigned char)((b32 >> 16) & 0xFF); | |
208 dest[1] = (unsigned char)((b32 >> 8) & 0xFF); | |
209 dest[2] = (unsigned char)((b32 ) & 0xFF); | |
210 | |
211 return PR_SUCCESS; | |
212 } | |
213 | |
214 static PRStatus | |
215 decode3to2 | |
216 ( | |
217 const unsigned char *src, | |
218 unsigned char *dest | |
219 ) | |
220 { | |
221 PRUint32 b32 = (PRUint32)0; | |
222 PRInt32 bits; | |
223 PRUint32 ubits; | |
224 | |
225 bits = codetovalue(src[0]); | |
226 if( bits < 0 ) | |
227 { | |
228 return PR_FAILURE; | |
229 } | |
230 | |
231 b32 = (PRUint32)bits; | |
232 b32 <<= 6; | |
233 | |
234 bits = codetovalue(src[1]); | |
235 if( bits < 0 ) | |
236 { | |
237 return PR_FAILURE; | |
238 } | |
239 | |
240 b32 |= (PRUint32)bits; | |
241 b32 <<= 4; | |
242 | |
243 bits = codetovalue(src[2]); | |
244 if( bits < 0 ) | |
245 { | |
246 return PR_FAILURE; | |
247 } | |
248 | |
249 ubits = (PRUint32)bits; | |
250 b32 |= (ubits >> 2); | |
251 | |
252 dest[0] = (unsigned char)((b32 >> 8) & 0xFF); | |
253 dest[1] = (unsigned char)((b32 ) & 0xFF); | |
254 | |
255 return PR_SUCCESS; | |
256 } | |
257 | |
258 static PRStatus | |
259 decode2to1 | |
260 ( | |
261 const unsigned char *src, | |
262 unsigned char *dest | |
263 ) | |
264 { | |
265 PRUint32 b32; | |
266 PRUint32 ubits; | |
267 PRInt32 bits; | |
268 | |
269 bits = codetovalue(src[0]); | |
270 if( bits < 0 ) | |
271 { | |
272 return PR_FAILURE; | |
273 } | |
274 | |
275 ubits = (PRUint32)bits; | |
276 b32 = (ubits << 2); | |
277 | |
278 bits = codetovalue(src[1]); | |
279 if( bits < 0 ) | |
280 { | |
281 return PR_FAILURE; | |
282 } | |
283 | |
284 ubits = (PRUint32)bits; | |
285 b32 |= (ubits >> 4); | |
286 | |
287 dest[0] = (unsigned char)b32; | |
288 | |
289 return PR_SUCCESS; | |
290 } | |
291 | |
292 static PRStatus | |
293 decode | |
294 ( | |
295 const unsigned char *src, | |
296 PRUint32 srclen, | |
297 unsigned char *dest | |
298 ) | |
299 { | |
300 PRStatus rv; | |
301 | |
302 while( srclen >= 4 ) | |
303 { | |
304 rv = decode4to3(src, dest); | |
305 if( PR_SUCCESS != rv ) | |
306 { | |
307 return PR_FAILURE; | |
308 } | |
309 | |
310 src += 4; | |
311 dest += 3; | |
312 srclen -= 4; | |
313 } | |
314 | |
315 switch( srclen ) | |
316 { | |
317 case 3: | |
318 rv = decode3to2(src, dest); | |
319 break; | |
320 case 2: | |
321 rv = decode2to1(src, dest); | |
322 break; | |
323 case 1: | |
324 rv = PR_FAILURE; | |
325 break; | |
326 case 0: | |
327 rv = PR_SUCCESS; | |
328 break; | |
329 default: | |
330 PR_NOT_REACHED("coding error"); | |
331 } | |
332 | |
333 return rv; | |
334 } | |
335 | |
336 /* | |
337 * PL_Base64Decode | |
338 * | |
339 * If the destination argument is NULL, a return buffer is | |
340 * allocated and the data therein will be null-terminated. | |
341 * If the destination argument is not null, it is assumed | |
342 * to be of sufficient size, and the data will not be null- | |
343 * terminated by this routine. | |
344 * | |
345 * Returns null if the allocation fails, or if the source string is | |
346 * not well-formed. | |
347 */ | |
348 | |
349 PR_IMPLEMENT(char *) | |
350 PL_Base64Decode | |
351 ( | |
352 const char *src, | |
353 PRUint32 srclen, | |
354 char *dest | |
355 ) | |
356 { | |
357 PRStatus status; | |
358 PRBool allocated = PR_FALSE; | |
359 | |
360 if( (char *)0 == src ) | |
361 { | |
362 return (char *)0; | |
363 } | |
364 | |
365 if( 0 == srclen ) | |
366 { | |
367 size_t len = strlen(src); | |
368 srclen = len; | |
369 /* Detect truncation. */ | |
370 if( srclen != len ) | |
371 { | |
372 return (char *)0; | |
373 } | |
374 } | |
375 | |
376 if( srclen && (0 == (srclen & 3)) ) | |
377 { | |
378 if( (char)'=' == src[ srclen-1 ] ) | |
379 { | |
380 if( (char)'=' == src[ srclen-2 ] ) | |
381 { | |
382 srclen -= 2; | |
383 } | |
384 else | |
385 { | |
386 srclen -= 1; | |
387 } | |
388 } | |
389 } | |
390 | |
391 if( (char *)0 == dest ) | |
392 { | |
393 /* The following computes ((srclen * 3) / 4) without overflow. */ | |
394 PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4; | |
395 dest = (char *)PR_MALLOC(destlen + 1); | |
396 if( (char *)0 == dest ) | |
397 { | |
398 return (char *)0; | |
399 } | |
400 dest[ destlen ] = (char)0; /* null terminate */ | |
401 allocated = PR_TRUE; | |
402 } | |
403 | |
404 status = decode((const unsigned char *)src, srclen, (unsigned char *)dest); | |
405 if( PR_SUCCESS != status ) | |
406 { | |
407 if( PR_TRUE == allocated ) | |
408 { | |
409 PR_DELETE(dest); | |
410 } | |
411 | |
412 return (char *)0; | |
413 } | |
414 | |
415 return dest; | |
416 } |