|
|
|
|
| 5 |
|
5 |
|
| 6 |
#include "plbase64.h" |
6 |
#include "plbase64.h" |
| 7 |
#include "prlog.h" /* For PR_NOT_REACHED */ |
7 |
#include "prlog.h" /* For PR_NOT_REACHED */ |
| 8 |
#include "prmem.h" /* for malloc / PR_MALLOC */ |
8 |
#include "prmem.h" /* for malloc / PR_MALLOC */ |
| 9 |
|
9 |
|
| 10 |
#include <string.h> /* for strlen */ |
10 |
#include <string.h> /* for strlen */ |
| 11 |
|
11 |
|
| 12 |
static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
12 |
static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|
|
13 |
static PRUint32 lenm = (PRUint32)0; |
| 14 |
static PRUint32 dcn = (PRUint32)0; |
| 13 |
|
15 |
|
| 14 |
static void |
16 |
static void |
| 15 |
encode3to4 |
17 |
encode3to4 |
| 16 |
( |
18 |
( |
| 17 |
const unsigned char *src, |
19 |
const unsigned char *src, |
| 18 |
unsigned char *dest |
20 |
unsigned char *dest |
| 19 |
) |
21 |
) |
| 20 |
{ |
22 |
{ |
|
|
| 147 |
|
149 |
|
| 148 |
encode((const unsigned char *)src, srclen, (unsigned char *)dest); |
150 |
encode((const unsigned char *)src, srclen, (unsigned char *)dest); |
| 149 |
return dest; |
151 |
return dest; |
| 150 |
} |
152 |
} |
| 151 |
|
153 |
|
| 152 |
static PRInt32 |
154 |
static PRInt32 |
| 153 |
codetovalue |
155 |
codetovalue |
| 154 |
( |
156 |
( |
| 155 |
unsigned char c |
157 |
const unsigned char *src, |
|
|
158 |
PRUint32 num |
| 156 |
) |
159 |
) |
| 157 |
{ |
160 |
{ |
|
|
161 |
unsigned char c = src[ num + lenm ]; |
| 158 |
if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) |
162 |
if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) |
| 159 |
{ |
163 |
{ |
| 160 |
return (PRInt32)(c - (unsigned char)'A'); |
164 |
return (PRInt32)(c - (unsigned char)'A'); |
| 161 |
} |
165 |
} |
| 162 |
else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) |
166 |
else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) |
| 163 |
{ |
167 |
{ |
| 164 |
return ((PRInt32)(c - (unsigned char)'a') +26); |
168 |
return ((PRInt32)(c - (unsigned char)'a') +26); |
| 165 |
} |
169 |
} |
|
|
| 170 |
else if( (unsigned char)'+' == c ) |
174 |
else if( (unsigned char)'+' == c ) |
| 171 |
{ |
175 |
{ |
| 172 |
return (PRInt32)62; |
176 |
return (PRInt32)62; |
| 173 |
} |
177 |
} |
| 174 |
else if( (unsigned char)'/' == c ) |
178 |
else if( (unsigned char)'/' == c ) |
| 175 |
{ |
179 |
{ |
| 176 |
return (PRInt32)63; |
180 |
return (PRInt32)63; |
| 177 |
} |
181 |
} |
|
|
182 |
else if( (unsigned char)'\0' == c ) |
| 183 |
{ |
| 184 |
return -2; |
| 185 |
} |
| 186 |
else if( (unsigned char)' ' == c || (unsigned char)'\r' == c || |
| 187 |
(unsigned char)'\n' == c || (unsigned char)'\t' == c || |
| 188 |
(unsigned char)'\f' == c ) |
| 189 |
{ |
| 190 |
lenm++; |
| 191 |
return codetovalue(src, num); |
| 192 |
} |
| 193 |
else if( (unsigned char)'=' == c) |
| 194 |
{ |
| 195 |
return -3; |
| 196 |
} |
| 178 |
else |
197 |
else |
| 179 |
{ |
198 |
{ |
| 180 |
return -1; |
199 |
return -1; |
| 181 |
} |
200 |
} |
| 182 |
} |
201 |
} |
| 183 |
|
202 |
|
| 184 |
static PRStatus |
203 |
static PRStatus |
| 185 |
decode4to3 |
204 |
decode4to3 |
| 186 |
( |
205 |
( |
| 187 |
const unsigned char *src, |
206 |
const unsigned char *src, |
| 188 |
unsigned char *dest |
207 |
unsigned char *dest |
| 189 |
) |
208 |
) |
| 190 |
{ |
209 |
{ |
| 191 |
PRUint32 b32 = (PRUint32)0; |
210 |
PRUint32 b32 = (PRUint32)0; |
| 192 |
PRInt32 bits; |
211 |
PRInt32 bits; |
| 193 |
PRIntn i; |
212 |
PRIntn i; |
|
|
213 |
PRUint32 tlm = lenm; |
| 194 |
|
214 |
|
| 195 |
for( i = 0; i < 4; i++ ) |
215 |
for( i = 0; i < 4; i++ ) |
| 196 |
{ |
216 |
{ |
| 197 |
bits = codetovalue(src[i]); |
217 |
bits = codetovalue(src, i); |
| 198 |
if( bits < 0 ) |
218 |
if( bits < 0 ) |
| 199 |
{ |
219 |
{ |
|
|
220 |
if( bits < -1 ) |
| 221 |
{ |
| 222 |
if( i == 0 ) |
| 223 |
{ |
| 224 |
return PR_SUCCESS; |
| 225 |
} |
| 226 |
else if( i == 1 ) |
| 227 |
{ |
| 228 |
return PR_FAILURE; |
| 229 |
} |
| 230 |
lenm = tlm; |
| 231 |
if( i == 2 ) |
| 232 |
{ |
| 233 |
dcn = 2; |
| 234 |
} |
| 235 |
else if( i == 3 ) |
| 236 |
{ |
| 237 |
dcn = 3; |
| 238 |
} |
| 239 |
} |
| 200 |
return PR_FAILURE; |
240 |
return PR_FAILURE; |
| 201 |
} |
241 |
} |
| 202 |
|
242 |
|
| 203 |
b32 <<= 6; |
243 |
b32 <<= 6; |
| 204 |
b32 |= bits; |
244 |
b32 |= bits; |
| 205 |
} |
245 |
} |
| 206 |
|
246 |
|
| 207 |
dest[0] = (unsigned char)((b32 >> 16) & 0xFF); |
247 |
dest[0] = (unsigned char)((b32 >> 16) & 0xFF); |
|
|
| 216 |
( |
256 |
( |
| 217 |
const unsigned char *src, |
257 |
const unsigned char *src, |
| 218 |
unsigned char *dest |
258 |
unsigned char *dest |
| 219 |
) |
259 |
) |
| 220 |
{ |
260 |
{ |
| 221 |
PRUint32 b32 = (PRUint32)0; |
261 |
PRUint32 b32 = (PRUint32)0; |
| 222 |
PRInt32 bits; |
262 |
PRInt32 bits; |
| 223 |
PRUint32 ubits; |
263 |
PRUint32 ubits; |
|
|
264 |
PRUint32 tlm = lenm; |
| 224 |
|
265 |
|
| 225 |
bits = codetovalue(src[0]); |
266 |
bits = codetovalue(src, 0); |
| 226 |
if( bits < 0 ) |
267 |
if( bits < 0 ) |
| 227 |
{ |
268 |
{ |
|
|
269 |
if( bits < -1 ) |
| 270 |
{ |
| 271 |
return PR_SUCCESS; |
| 272 |
} |
| 228 |
return PR_FAILURE; |
273 |
return PR_FAILURE; |
| 229 |
} |
274 |
} |
| 230 |
|
275 |
|
| 231 |
b32 = (PRUint32)bits; |
276 |
b32 = (PRUint32)bits; |
| 232 |
b32 <<= 6; |
277 |
b32 <<= 6; |
| 233 |
|
278 |
|
| 234 |
bits = codetovalue(src[1]); |
279 |
bits = codetovalue(src, 1); |
| 235 |
if( bits < 0 ) |
280 |
if( bits < 0 ) |
| 236 |
{ |
281 |
{ |
| 237 |
return PR_FAILURE; |
282 |
return PR_FAILURE; |
| 238 |
} |
283 |
} |
| 239 |
|
284 |
|
| 240 |
b32 |= (PRUint32)bits; |
285 |
b32 |= (PRUint32)bits; |
| 241 |
b32 <<= 4; |
286 |
b32 <<= 4; |
| 242 |
|
287 |
|
| 243 |
bits = codetovalue(src[2]); |
288 |
//tlm = lenm; |
|
|
289 |
bits = codetovalue(src, 2); |
| 244 |
if( bits < 0 ) |
290 |
if( bits < 0 ) |
| 245 |
{ |
291 |
{ |
|
|
292 |
if( bits < -1 ) |
| 293 |
{ |
| 294 |
lenm = tlm; |
| 295 |
dcn = 2; |
| 296 |
} |
| 246 |
return PR_FAILURE; |
297 |
return PR_FAILURE; |
| 247 |
} |
298 |
} |
| 248 |
|
299 |
|
| 249 |
ubits = (PRUint32)bits; |
300 |
ubits = (PRUint32)bits; |
| 250 |
b32 |= (ubits >> 2); |
301 |
b32 |= (ubits >> 2); |
| 251 |
|
302 |
|
| 252 |
dest[0] = (unsigned char)((b32 >> 8) & 0xFF); |
303 |
dest[0] = (unsigned char)((b32 >> 8) & 0xFF); |
| 253 |
dest[1] = (unsigned char)((b32 ) & 0xFF); |
304 |
dest[1] = (unsigned char)((b32 ) & 0xFF); |
|
|
| 261 |
const unsigned char *src, |
312 |
const unsigned char *src, |
| 262 |
unsigned char *dest |
313 |
unsigned char *dest |
| 263 |
) |
314 |
) |
| 264 |
{ |
315 |
{ |
| 265 |
PRUint32 b32; |
316 |
PRUint32 b32; |
| 266 |
PRUint32 ubits; |
317 |
PRUint32 ubits; |
| 267 |
PRInt32 bits; |
318 |
PRInt32 bits; |
| 268 |
|
319 |
|
| 269 |
bits = codetovalue(src[0]); |
320 |
bits = codetovalue(src, 0); |
| 270 |
if( bits < 0 ) |
321 |
if( bits < 0 ) |
| 271 |
{ |
322 |
{ |
|
|
323 |
if( bits < -1 ) |
| 324 |
{ |
| 325 |
return PR_SUCCESS; |
| 326 |
} |
| 272 |
return PR_FAILURE; |
327 |
return PR_FAILURE; |
| 273 |
} |
328 |
} |
| 274 |
|
329 |
|
| 275 |
ubits = (PRUint32)bits; |
330 |
ubits = (PRUint32)bits; |
| 276 |
b32 = (ubits << 2); |
331 |
b32 = (ubits << 2); |
| 277 |
|
332 |
|
| 278 |
bits = codetovalue(src[1]); |
333 |
bits = codetovalue(src, 1); |
| 279 |
if( bits < 0 ) |
334 |
if( bits < 0 ) |
| 280 |
{ |
335 |
{ |
| 281 |
return PR_FAILURE; |
336 |
return PR_FAILURE; |
| 282 |
} |
337 |
} |
| 283 |
|
338 |
|
| 284 |
ubits = (PRUint32)bits; |
339 |
ubits = (PRUint32)bits; |
| 285 |
b32 |= (ubits >> 4); |
340 |
b32 |= (ubits >> 4); |
| 286 |
|
341 |
|
|
|
| 294 |
( |
349 |
( |
| 295 |
const unsigned char *src, |
350 |
const unsigned char *src, |
| 296 |
PRUint32 srclen, |
351 |
PRUint32 srclen, |
| 297 |
unsigned char *dest |
352 |
unsigned char *dest |
| 298 |
) |
353 |
) |
| 299 |
{ |
354 |
{ |
| 300 |
PRStatus rv; |
355 |
PRStatus rv; |
| 301 |
|
356 |
|
| 302 |
while( srclen >= 4 ) |
357 |
lenm = 0; |
|
|
358 |
dcn = 0; |
| 359 |
while( ( srclen - lenm ) >= 4 ) |
| 303 |
{ |
360 |
{ |
| 304 |
rv = decode4to3(src, dest); |
361 |
rv = decode4to3(src, dest); |
| 305 |
if( PR_SUCCESS != rv ) |
362 |
if( PR_SUCCESS != rv ) |
| 306 |
{ |
363 |
{ |
|
|
364 |
if( dcn ) |
| 365 |
{ |
| 366 |
if( dcn == 3 ) |
| 367 |
{ |
| 368 |
return decode3to2(src, dest); |
| 369 |
} |
| 370 |
else if( dcn == 2 ) |
| 371 |
{ |
| 372 |
return decode2to1(src, dest); |
| 373 |
} |
| 374 |
else |
| 375 |
{ |
| 376 |
PR_NOT_REACHED("coding error"); |
| 377 |
} |
| 378 |
} |
| 307 |
return PR_FAILURE; |
379 |
return PR_FAILURE; |
| 308 |
} |
380 |
} |
| 309 |
|
381 |
|
| 310 |
src += 4; |
382 |
src += 4; |
| 311 |
dest += 3; |
383 |
dest += 3; |
| 312 |
srclen -= 4; |
384 |
srclen -= 4; |
| 313 |
} |
385 |
} |
| 314 |
|
386 |
|
| 315 |
switch( srclen ) |
387 |
switch( srclen - lenm ) |
| 316 |
{ |
388 |
{ |
| 317 |
case 3: |
389 |
case 3: |
| 318 |
rv = decode3to2(src, dest); |
390 |
rv = decode3to2(src, dest); |
| 319 |
break; |
391 |
break; |
| 320 |
case 2: |
392 |
case 2: |
| 321 |
rv = decode2to1(src, dest); |
393 |
rv = decode2to1(src, dest); |
| 322 |
break; |
394 |
break; |
| 323 |
case 1: |
395 |
case 1: |
|
|
| 350 |
PL_Base64Decode |
422 |
PL_Base64Decode |
| 351 |
( |
423 |
( |
| 352 |
const char *src, |
424 |
const char *src, |
| 353 |
PRUint32 srclen, |
425 |
PRUint32 srclen, |
| 354 |
char *dest |
426 |
char *dest |
| 355 |
) |
427 |
) |
| 356 |
{ |
428 |
{ |
| 357 |
PRStatus status; |
429 |
PRStatus status; |
|
|
430 |
PRUint32 i; |
| 358 |
PRBool allocated = PR_FALSE; |
431 |
PRBool allocated = PR_FALSE; |
| 359 |
|
432 |
|
| 360 |
if( (char *)0 == src ) |
433 |
if( (char *)0 == src ) |
| 361 |
{ |
434 |
{ |
| 362 |
return (char *)0; |
435 |
return (char *)0; |
| 363 |
} |
436 |
} |
| 364 |
|
437 |
|
| 365 |
if( 0 == srclen ) |
438 |
if( 0 == srclen ) |
| 366 |
{ |
439 |
{ |
| 367 |
size_t len = strlen(src); |
440 |
size_t len = strlen(src); |
| 368 |
srclen = len; |
441 |
srclen = len; |
| 369 |
/* Detect truncation. */ |
442 |
/* Detect truncation. */ |
| 370 |
if( srclen != len ) |
443 |
if( srclen != len ) |
| 371 |
{ |
444 |
{ |
| 372 |
return (char *)0; |
445 |
return (char *)0; |
| 373 |
} |
446 |
} |
|
|
447 |
for( i = 0; i < strlen(src); i++ ) { |
| 448 |
if ( (unsigned char)' ' == src[i] || (unsigned char)'\r' == src[i] || |
| 449 |
(unsigned char)'\n' == src[i] || (unsigned char)'\t' == src[i] || |
| 450 |
(unsigned char)'\f' == src[i] ) { |
| 451 |
srclen -= 1; |
| 452 |
} |
| 453 |
} |
| 374 |
} |
454 |
} |
| 375 |
|
455 |
|
| 376 |
if( srclen && (0 == (srclen & 3)) ) |
456 |
if( srclen && (0 == (srclen & 3)) ) |
| 377 |
{ |
457 |
{ |
| 378 |
if( (char)'=' == src[ srclen-1 ] ) |
458 |
if( (char)'=' == src[ srclen-1 ] ) |
| 379 |
{ |
459 |
{ |
| 380 |
if( (char)'=' == src[ srclen-2 ] ) |
460 |
if( (char)'=' == src[ srclen-2 ] ) |
| 381 |
{ |
461 |
{ |