Attachment #780030: Proposed patch v1.1 for bug #711180

View | Details | Raw Unified | Return to bug 711180
Collapse All | Expand All

(-)a/nsprpub/lib/libc/src/base64.c (-9 / +89 lines)
Line     Link Here 
 Lines 5-20    Link Here 
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
{
 Lines 147-165   PL_Base64Encode Link Here 
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
    }
 Lines 170-207   codetovalue Link Here 
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);
 Lines 216-253   decode3to2 Link Here 
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);
 Lines 261-286   decode2to1 Link Here 
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
 Lines 294-323   decode Link Here 
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:
 Lines 350-381   PR_IMPLEMENT(char *) Link Here 
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
            {
(-)a/xpcom/io/Base64.cpp (-3 / +44 lines)
Line     Link Here 
 Lines 1-15    Link Here 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
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
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/. */
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
5
6
#include "Base64.h"
6
#include "Base64.h"
7
7
8
#include <math.h>
9
8
#include "nsIInputStream.h"
10
#include "nsIInputStream.h"
9
#include "nsStringGlue.h"
11
#include "nsStringGlue.h"
10
12
11
#include "plbase64.h"
13
#include "plbase64.h"
12
14
13
namespace {
15
namespace {
14
16
15
// BEGIN base64 encode code copied and modified from NSPR
17
// BEGIN base64 encode code copied and modified from NSPR
 Lines 293-311   Base64Decode(const nsACString &aString, Link Here 
293
    return NS_ERROR_FAILURE;
295
    return NS_ERROR_FAILURE;
294
  }
296
  }
295
297
296
  // Don't ask PR_Base64Decode to decode the empty string
298
  // Don't ask PR_Base64Decode to decode the empty string
297
  if (aString.IsEmpty()) {
299
  if (aString.IsEmpty()) {
298
    aBinaryData.Truncate();
300
    aBinaryData.Truncate();
299
    return NS_OK;
301
    return NS_OK;
300
  }
302
  }
303
  
304
  int32_t binaryDataLen = ((aString.Length() * 3) / 4);
301
305
302
  uint32_t binaryDataLen = ((aString.Length() * 3) / 4);
306
  const char *tmp = aString.BeginReading();
303
307
  uint32_t i;
308
  uint32_t e = 0;
309
  bool eis = false;
310
  bool sae = false;
311
  for( i = 0; i < aString.Length(); i++ ) {
312
    if ( (unsigned char)' ' == tmp[i] || (unsigned char)'\r' == tmp[i] ||
313
    (unsigned char)'\n' == tmp[i] || (unsigned char)'\t' == tmp[i] ||
314
    (unsigned char)'\f' == tmp[i] ) {
315
      binaryDataLen -= 1;
316
	  if ( eis && !sae ) {
317
        binaryDataLen -= 1;
318
		sae = true;
319
	  }
320
    }
321
	else if ( (unsigned char)'=' == tmp[i] ) {
322
	  binaryDataLen -= 1;
323
	  e += 1;
324
	  eis = true;
325
	  if ( e > 2 ) {
326
        aBinaryData.Truncate();
327
		return NS_ERROR_INVALID_ARG;
328
	  }
329
	}
330
	else if ( eis ) {
331
      aBinaryData.Truncate();
332
      return NS_ERROR_INVALID_ARG;
333
	}
334
  }
335
  if (i != 0) {
336
    binaryDataLen += 1;
337
  }
338
  if (i > 4) {
339
    if (i % 4 == 0) {
340
      binaryDataLen -= 1;
341
    }
342
    binaryDataLen += ceil( (float)( (i - 4) / 4 ) );
343
  }
304
  char *buffer;
344
  char *buffer;
305
345
306
  // Add one byte for null termination.
346
  // Add one byte for null termination.
307
  if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible_t()) &&
347
  if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible_t()) &&
308
    (buffer = aBinaryData.BeginWriting()) &&
348
    (buffer = aBinaryData.BeginWriting()) &&
309
    PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) {
349
    PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) {
310
    // PL_Base64Decode doesn't null terminate the buffer for us when we pass
350
    // PL_Base64Decode doesn't null terminate the buffer for us when we pass
311
    // the buffer in. Do that manually, taking into account the number of '='
351
    // the buffer in. Do that manually, taking into account the number of '='
 Lines 313-333   Base64Decode(const nsACString &aString, Link Here 
313
    if (!aString.IsEmpty() && aString[aString.Length() - 1] == '=') {
353
    if (!aString.IsEmpty() && aString[aString.Length() - 1] == '=') {
314
      if (aString.Length() > 1 && aString[aString.Length() - 2] == '=') {
354
      if (aString.Length() > 1 && aString[aString.Length() - 2] == '=') {
315
        binaryDataLen -= 2;
355
        binaryDataLen -= 2;
316
      } else {
356
      } else {
317
        binaryDataLen -= 1;
357
        binaryDataLen -= 1;
318
      }
358
      }
319
    }
359
    }
320
    buffer[binaryDataLen] = '\0';
360
    buffer[binaryDataLen] = '\0';
321
361
  
322
    aBinaryData.SetLength(binaryDataLen);
362
    aBinaryData.SetLength(binaryDataLen);
323
    return NS_OK;
363
    return NS_OK;
324
  }
364
  }
325
365
366
326
  aBinaryData.Truncate();
367
  aBinaryData.Truncate();
327
  return NS_ERROR_INVALID_ARG;
368
  return NS_ERROR_INVALID_ARG;
328
}
369
}
329
370
330
nsresult
371
nsresult
331
Base64Decode(const nsAString &aBinaryData, nsAString &aString)
372
Base64Decode(const nsAString &aBinaryData, nsAString &aString)
332
{
373
{
333
  NS_LossyConvertUTF16toASCII binaryData(aBinaryData);
374
  NS_LossyConvertUTF16toASCII binaryData(aBinaryData);

Return to bug 711180