cherry-picked mozilla NSS upstream changes (to rev 632864c9, which is on par with 3.21.4):
bug1221620, bug1244324, bug1241034, bug1206283, bug1241037, bug1245528, bug1293334, bug1306103, bug1345089, bug1344380
This commit is contained in:
parent
9b2e59866b
commit
6712ac7edb
|
@ -61,6 +61,12 @@ ifndef WARNING_CFLAGS
|
|||
|
||||
ifeq ($(NSS_ENABLE_WERROR),1)
|
||||
WARNING_CFLAGS += -Werror
|
||||
# For gcc 6 and newer we need -Wno-error=misleading-indentation
|
||||
# to prevent compiler errors caused by mixed whitespace.
|
||||
CC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
|
||||
ifeq (,$(filter 0 1 2 3 4 5,$(word 1,$(CC_VERSION))))
|
||||
WARNING_CFLAGS += -Wno-error=misleading-indentation
|
||||
endif
|
||||
else
|
||||
# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
|
||||
# Use this to disable use of that #pragma and the warnings it suppresses.
|
||||
|
|
|
@ -1444,6 +1444,12 @@ FIPS186Change_ReduceModQForDSA(const unsigned char *w,
|
|||
const unsigned char *q,
|
||||
unsigned char *xj);
|
||||
|
||||
/* To allow NIST KAT tests */
|
||||
extern SECStatus
|
||||
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
|
||||
const PRUint8 *nonce, unsigned int nonce_len,
|
||||
const PRUint8 *personal_string, unsigned int ps_len);
|
||||
|
||||
/*
|
||||
* The following functions are for FIPS poweron self test and FIPS algorithm
|
||||
* testing.
|
||||
|
|
|
@ -96,7 +96,8 @@ struct RNGContextStr {
|
|||
* RNG_RandomUpdate. */
|
||||
PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
|
||||
PRUint32 additionalAvail;
|
||||
PRBool isValid; /* false if RNG reaches an invalid state */
|
||||
PRBool isValid; /* false if RNG reaches an invalid state */
|
||||
PRBool isKatTest; /* true if running NIST PRNG KAT tests */
|
||||
};
|
||||
|
||||
typedef struct RNGContextStr RNGContext;
|
||||
|
@ -149,7 +150,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
|||
|
||||
|
||||
/*
|
||||
* Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2
|
||||
* Hash_DRBG Instantiate NIST SP 800-90 10.1.1.2
|
||||
*
|
||||
* NOTE: bytes & len are entropy || nonce || personalization_string. In
|
||||
* normal operation, NSS calculates them all together in a single call.
|
||||
|
@ -157,9 +158,11 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
|||
static SECStatus
|
||||
prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
|
||||
{
|
||||
if (len < PRNG_SEEDLEN) {
|
||||
/* if the seedlen is to small, it's probably because we failed to get
|
||||
* enough random data */
|
||||
if (!rng->isKatTest && len < PRNG_SEEDLEN) {
|
||||
/* If the seedlen is too small, it's probably because we failed to get
|
||||
* enough random data.
|
||||
* This is stricter than NIST SP800-90A requires. Don't enforce it for
|
||||
* tests. */
|
||||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -272,7 +275,7 @@ prng_reseed_test(RNGContext *rng, const PRUint8 *entropy,
|
|||
|
||||
#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \
|
||||
PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
|
||||
PRNG_ADD_CARRY_ONLY(dest, dest_len - len, carry)
|
||||
PRNG_ADD_CARRY_ONLY(dest, dest_len - len - 1, carry)
|
||||
|
||||
/*
|
||||
* This function expands the internal state of the prng to fulfill any number
|
||||
|
@ -423,6 +426,7 @@ static PRStatus rng_init(void)
|
|||
}
|
||||
/* the RNG is in a valid state */
|
||||
globalrng->isValid = PR_TRUE;
|
||||
globalrng->isKatTest = PR_FALSE;
|
||||
|
||||
/* fetch one random value so that we can populate rng->oldV for our
|
||||
* continous random number test. */
|
||||
|
@ -667,6 +671,17 @@ RNG_RNGShutdown(void)
|
|||
* entropy we may have previously collected. */
|
||||
RNGContext testContext;
|
||||
|
||||
SECStatus
|
||||
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
|
||||
const PRUint8 *nonce, unsigned int nonce_len,
|
||||
const PRUint8 *personal_string, unsigned int ps_len)
|
||||
{
|
||||
testContext.isKatTest = PR_TRUE;
|
||||
return PRNGTEST_Instantiate(entropy, entropy_len,
|
||||
nonce, nonce_len,
|
||||
personal_string, ps_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test vector API. Use NIST SP 800-90 general interface so one of the
|
||||
* other NIST SP 800-90 algorithms may be used in the future.
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.21" _NSS_ECC_STRING _NSS_CUSTOMIZED
|
||||
#define NSS_VERSION "3.21.4" _NSS_ECC_STRING _NSS_CUSTOMIZED
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 21
|
||||
#define NSS_VPATCH 0
|
||||
#define NSS_VPATCH 4
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_FALSE
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define SOFTOKEN_VERSION "3.21" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VERSION "3.21.4" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VMAJOR 3
|
||||
#define SOFTOKEN_VMINOR 21
|
||||
#define SOFTOKEN_VPATCH 0
|
||||
#define SOFTOKEN_VPATCH 4
|
||||
#define SOFTOKEN_VBUILD 0
|
||||
#define SOFTOKEN_BETA PR_FALSE
|
||||
|
||||
|
|
|
@ -9963,6 +9963,7 @@ ssl3_HandleDHClientKeyExchange(sslSocket *ss,
|
|||
CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);
|
||||
if (pms == NULL) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
|
@ -11867,6 +11868,13 @@ ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
|
|||
return DUPLICATE_MSB_TO_ALL_8(c);
|
||||
}
|
||||
|
||||
/* ssl_constantTimeSelect return a if mask is 0xFF and b if mask is 0x00 */
|
||||
static unsigned char
|
||||
ssl_constantTimeSelect(unsigned char mask, unsigned char a, unsigned char b)
|
||||
{
|
||||
return (mask & a) | (~mask & b);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
|
||||
unsigned int blockSize,
|
||||
|
@ -11970,22 +11978,54 @@ ssl_CBCExtractMAC(sslBuffer *plaintext,
|
|||
/* scanStart contains the number of bytes that we can ignore because
|
||||
* the MAC's position can only vary by 255 bytes. */
|
||||
unsigned scanStart = 0;
|
||||
unsigned i, j, divSpoiler;
|
||||
unsigned i, j;
|
||||
unsigned char rotateOffset;
|
||||
|
||||
if (originalLength > macSize + 255 + 1)
|
||||
if (originalLength > macSize + 255 + 1) {
|
||||
scanStart = originalLength - (macSize + 255 + 1);
|
||||
}
|
||||
|
||||
/* divSpoiler contains a multiple of macSize that is used to cause the
|
||||
* modulo operation to be constant time. Without this, the time varies
|
||||
* based on the amount of padding when running on Intel chips at least.
|
||||
*
|
||||
* The aim of right-shifting macSize is so that the compiler doesn't
|
||||
* figure out that it can remove divSpoiler as that would require it
|
||||
* to prove that macSize is always even, which I hope is beyond it. */
|
||||
divSpoiler = macSize >> 1;
|
||||
divSpoiler <<= (sizeof(divSpoiler)-1)*8;
|
||||
rotateOffset = (divSpoiler + macStart - scanStart) % macSize;
|
||||
/* We want to compute
|
||||
* rotateOffset = (macStart - scanStart) % macSize
|
||||
* But the time to compute this varies based on the amount of padding. Thus
|
||||
* we explicitely handle all mac sizes with (hopefully) constant time modulo
|
||||
* using Barrett reduction:
|
||||
* q := (rotateOffset * m) >> k
|
||||
* rotateOffset -= q * n
|
||||
* if (n <= rotateOffset) rotateOffset -= n
|
||||
*/
|
||||
rotateOffset = macStart - scanStart;
|
||||
/* rotateOffset < 255 + 1 + 48 = 304 */
|
||||
if (macSize == 16) {
|
||||
rotateOffset &= 15;
|
||||
} else if (macSize == 20) {
|
||||
/*
|
||||
* Correctness: rotateOffset * ( 1/20 - 25/2^9 ) < 1
|
||||
* with rotateOffset <= 853
|
||||
*/
|
||||
unsigned q = (rotateOffset * 25) >> 9; /* m = 25, k = 9 */
|
||||
rotateOffset -= q * 20;
|
||||
rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, 20),
|
||||
20, 0);
|
||||
} else if (macSize == 32) {
|
||||
rotateOffset &= 31;
|
||||
} else if (macSize == 48) {
|
||||
/*
|
||||
* Correctness: rotateOffset * ( 1/48 - 10/2^9 ) < 1
|
||||
* with rotateOffset < 768
|
||||
*/
|
||||
unsigned q = (rotateOffset * 10) >> 9; /* m = 25, k = 9 */
|
||||
rotateOffset -= q * 48;
|
||||
rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, 48),
|
||||
48, 0);
|
||||
} else {
|
||||
/*
|
||||
* SHA384 (macSize == 48) is the largest we support. We should never
|
||||
* get here.
|
||||
*/
|
||||
PORT_Assert(0);
|
||||
rotateOffset = rotateOffset % macSize;
|
||||
}
|
||||
|
||||
memset(rotatedMac, 0, macSize);
|
||||
for (i = scanStart; i < originalLength;) {
|
||||
|
@ -12001,12 +12041,16 @@ ssl_CBCExtractMAC(sslBuffer *plaintext,
|
|||
/* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line
|
||||
* we could line-align |rotatedMac| and rotate in place. */
|
||||
memset(out, 0, macSize);
|
||||
rotateOffset = macSize - rotateOffset;
|
||||
rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize),
|
||||
0, rotateOffset);
|
||||
for (i = 0; i < macSize; i++) {
|
||||
unsigned char offset =
|
||||
(divSpoiler + macSize - rotateOffset + i) % macSize;
|
||||
for (j = 0; j < macSize; j++) {
|
||||
out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
|
||||
}
|
||||
out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, rotateOffset);
|
||||
}
|
||||
rotateOffset++;
|
||||
rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize),
|
||||
0, rotateOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,10 +179,12 @@ long
|
|||
DER_GetInteger(const SECItem *it)
|
||||
{
|
||||
long ival = 0;
|
||||
unsigned len = it->len;
|
||||
PRBool negative = PR_FALSE;
|
||||
unsigned int len = it->len;
|
||||
unsigned int originalLength = len;
|
||||
unsigned char *cp = it->data;
|
||||
unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
|
||||
unsigned long ofloinit;
|
||||
unsigned long mask = 1;
|
||||
|
||||
PORT_Assert(len);
|
||||
if (!len) {
|
||||
|
@ -190,14 +192,15 @@ DER_GetInteger(const SECItem *it)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (*cp & 0x80)
|
||||
ival = -1L;
|
||||
ofloinit = ival & overflow;
|
||||
if (*cp & 0x80) {
|
||||
negative = PR_TRUE;
|
||||
overflow <<= 1;
|
||||
}
|
||||
|
||||
while (len) {
|
||||
if ((ival & overflow) != ofloinit) {
|
||||
if ((ival & overflow) != 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
if (ival < 0) {
|
||||
if (negative) {
|
||||
return LONG_MIN;
|
||||
}
|
||||
return LONG_MAX;
|
||||
|
@ -206,6 +209,11 @@ DER_GetInteger(const SECItem *it)
|
|||
ival |= *cp++;
|
||||
--len;
|
||||
}
|
||||
if (negative && ival && (overflow & ival) == 0) {
|
||||
mask <<= ((originalLength * 8) - 1);
|
||||
ival &= ~mask;
|
||||
ival -= mask;
|
||||
}
|
||||
return ival;
|
||||
}
|
||||
|
||||
|
|
|
@ -373,7 +373,7 @@ pl_base64_decode_flush (PLBase64Decoder *data)
|
|||
static PRUint32
|
||||
PL_Base64MaxDecodedLength (PRUint32 size)
|
||||
{
|
||||
return ((size * 3) / 4);
|
||||
return size * 0.75;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -285,6 +285,11 @@ PL_Base64MaxEncodedLength (PRUint32 size, PRUint32 line_length)
|
|||
{
|
||||
PRUint32 tokens, tokens_per_line, full_lines, line_break_chars, remainder;
|
||||
|
||||
/* This is the maximum length we support. */
|
||||
if (size > 0x3fffffff) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tokens = (size + 2) / 3;
|
||||
|
||||
if (line_length == 0)
|
||||
|
@ -461,6 +466,10 @@ PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
|
|||
* How much space could we possibly need for encoding this input?
|
||||
*/
|
||||
need_length = PL_Base64MaxEncodedLength (srclen, line_length);
|
||||
if (need_length == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we have at least that much, if output buffer provided.
|
||||
|
@ -643,6 +652,10 @@ NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
|
|||
}
|
||||
|
||||
max_out_len = PL_Base64MaxEncodedLength (inItem->len, 64);
|
||||
if (max_out_len == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (arenaOpt != NULL)
|
||||
mark = PORT_ArenaMark (arenaOpt);
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
|
||||
*/
|
||||
#define NSSUTIL_VERSION "3.21"
|
||||
#define NSSUTIL_VERSION "3.21.4"
|
||||
#define NSSUTIL_VMAJOR 3
|
||||
#define NSSUTIL_VMINOR 21
|
||||
#define NSSUTIL_VPATCH 0
|
||||
#define NSSUTIL_VPATCH 4
|
||||
#define NSSUTIL_VBUILD 0
|
||||
#define NSSUTIL_BETA PR_FALSE
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define PR_Assert sec_asn1d_Assert
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
|
||||
|
@ -1593,6 +1595,7 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
|
|||
|
||||
item = (SECItem *)(state->dest);
|
||||
if (item != NULL && item->data != NULL) {
|
||||
unsigned long offset;
|
||||
/* Strip leading zeroes when target is unsigned integer */
|
||||
if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
|
||||
item->len == 0 && /* MSB */
|
||||
|
@ -1603,8 +1606,42 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
|
|||
len--;
|
||||
}
|
||||
}
|
||||
PORT_Memcpy (item->data + item->len, buf, len);
|
||||
item->len += len;
|
||||
offset = item->len;
|
||||
if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
|
||||
// The previous bit string must have no unused bits.
|
||||
if (item->len & 0x7) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
// If this is a bit string, the length is bits, not bytes.
|
||||
offset = item->len >> 3;
|
||||
}
|
||||
if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
|
||||
unsigned long len_in_bits;
|
||||
// Protect against overflow during the bytes-to-bits conversion.
|
||||
if (len >= (ULONG_MAX >> 3) + 1) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
len_in_bits = (len << 3) - state->bit_string_unused_bits;
|
||||
// Protect against overflow when computing the total length in bits.
|
||||
if (UINT_MAX - item->len < len_in_bits) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
item->len += len_in_bits;
|
||||
} else {
|
||||
if (UINT_MAX - item->len < len) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
item->len += len;
|
||||
}
|
||||
PORT_Memcpy (item->data + offset, buf, len);
|
||||
}
|
||||
state->pending -= bufLen;
|
||||
if (state->pending == 0)
|
||||
|
@ -1671,14 +1708,6 @@ sec_asn1d_parse_more_bit_string (sec_asn1d_state *state,
|
|||
}
|
||||
|
||||
len = sec_asn1d_parse_leaf (state, buf, len);
|
||||
if (state->place == beforeEndOfContents && state->dest != NULL) {
|
||||
SECItem *item;
|
||||
|
||||
item = (SECItem *)(state->dest);
|
||||
if (item->len)
|
||||
item->len = (item->len << 3) - state->bit_string_unused_bits;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -2208,7 +2237,7 @@ sec_asn1d_concat_substrings (sec_asn1d_state *state)
|
|||
* All bit-string substrings except the last one should be
|
||||
* a clean multiple of 8 bits.
|
||||
*/
|
||||
if (is_bit_string && (substring->next == NULL)
|
||||
if (is_bit_string && (substring->next != NULL)
|
||||
&& (substring->len & 0x7)) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
|
|
|
@ -319,10 +319,10 @@ sec_port_ucs2_utf8_conversion_function
|
|||
}
|
||||
|
||||
for( i = 0; i < inBufLen; i += 2 ) {
|
||||
if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_0] & 0x80) == 0x00) ) len += 1;
|
||||
if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_1] & 0x80) == 0x00) ) len += 1;
|
||||
else if( inBuf[i+H_0] < 0x08 ) len += 2;
|
||||
else if( ((inBuf[i+0+H_0] & 0xDC) == 0xD8) ) {
|
||||
if( ((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2) ) {
|
||||
else if( ((inBuf[i+0+H_0] & 0xFC) == 0xD8) ) {
|
||||
if( ((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xFC) == 0xDC) ) {
|
||||
i += 2;
|
||||
len += 4;
|
||||
} else {
|
||||
|
@ -356,10 +356,10 @@ sec_port_ucs2_utf8_conversion_function
|
|||
outBuf[len+1] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
|
||||
|
||||
len += 2;
|
||||
} else if( (inBuf[i+H_0] & 0xDC) == 0xD8 ) {
|
||||
} else if( (inBuf[i+H_0] & 0xFC) == 0xD8 ) {
|
||||
int abcde, BCDE;
|
||||
|
||||
PORT_Assert(((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2));
|
||||
PORT_Assert(((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xFC) == 0xDC) );
|
||||
|
||||
/* D800-DBFF DC00-DFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||
/* 110110BC DEfghijk 110111lm nopqrstu ->
|
||||
|
@ -852,6 +852,7 @@ struct ucs2 ucs2[] = {
|
|||
{ 0x9000, "\xE9\x80\x80" },
|
||||
{ 0xA000, "\xEA\x80\x80" },
|
||||
{ 0xC000, "\xEC\x80\x80" },
|
||||
{ 0xFB01, "\xEF\xAC\x81" },
|
||||
{ 0xFFFF, "\xEF\xBF\xBF" }
|
||||
|
||||
};
|
||||
|
@ -1153,6 +1154,18 @@ char *utf8_bad[] = {
|
|||
"\xED\xA0\x80\xE0\xBF\xBF",
|
||||
};
|
||||
|
||||
/* illegal UTF-16 sequences, 0-terminated */
|
||||
uint16_t utf16_bad[][3] = {
|
||||
/* leading surrogate not followed by trailing surrogate */
|
||||
{ 0xD800, 0, 0 },
|
||||
{ 0xD800, 0x41, 0 },
|
||||
{ 0xD800, 0xfe, 0 },
|
||||
{ 0xD800, 0x3bb, 0 },
|
||||
{ 0xD800, 0xD800, 0 },
|
||||
{ 0xD800, 0xFEFF, 0 },
|
||||
{ 0xD800, 0xFFFD, 0 },
|
||||
};
|
||||
|
||||
static void
|
||||
dump_utf8
|
||||
(
|
||||
|
@ -1220,6 +1233,18 @@ test_ucs4_chars
|
|||
rv = PR_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = strlen(e->utf8) - 1;
|
||||
result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
|
||||
(unsigned char *)&e->c, sizeof(e->c), utf8 + sizeof(utf8) - len, len,
|
||||
&len);
|
||||
|
||||
if( result || len != strlen(e->utf8) ) {
|
||||
fprintf(stdout, "Length computation error converting UCS-4 0x%08.8x"
|
||||
" to UTF-8\n", e->c);
|
||||
rv = PR_FALSE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -1277,6 +1302,18 @@ test_ucs2_chars
|
|||
rv = PR_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = strlen(e->utf8) - 1;
|
||||
result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
|
||||
(unsigned char *)&e->c, sizeof(e->c), utf8 + sizeof(utf8) - len, len,
|
||||
&len);
|
||||
|
||||
if( result || len != strlen(e->utf8) ) {
|
||||
fprintf(stdout, "Length computation error converting UCS-2 0x%04.4x"
|
||||
" to UTF-8\n", e->c);
|
||||
rv = PR_FALSE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -1426,6 +1463,38 @@ test_utf8_bad_chars
|
|||
return rv;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
test_utf16_bad_chars(void)
|
||||
{
|
||||
PRBool rv = PR_TRUE;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < sizeof(utf16_bad)/sizeof(utf16_bad[0]); ++i ) {
|
||||
PRBool result;
|
||||
unsigned char destbuf[18];
|
||||
unsigned int j, len, destlen;
|
||||
uint16_t *buf;
|
||||
|
||||
for( len = 0; utf16_bad[i][len] != 0; ++len )
|
||||
/* nothing */;
|
||||
|
||||
buf = malloc(sizeof(uint16_t) * len);
|
||||
for( j = 0; j < len; ++j )
|
||||
buf[j] = htons(utf16_bad[i][j]);
|
||||
|
||||
result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
|
||||
(unsigned char *)buf, sizeof(uint16_t) * len, destbuf, sizeof(destbuf),
|
||||
&destlen);
|
||||
if( result ) {
|
||||
fprintf(stdout, "Failed to detect bad UTF-16 string conversion for "
|
||||
"{0x%x,0x%x} (UTF-8 len = %u)\n", utf16_bad[i][0], utf16_bad[i][1],
|
||||
destlen);
|
||||
rv = PR_FALSE;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool
|
||||
test_iso88591_chars
|
||||
(
|
||||
|
@ -1576,7 +1645,7 @@ test_multichars
|
|||
exit(1);
|
||||
}
|
||||
|
||||
len = 0;
|
||||
len = 1;
|
||||
for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
|
||||
ucs4s[i] = ucs4[i].c;
|
||||
len += strlen(ucs4[i].utf8);
|
||||
|
@ -1584,7 +1653,7 @@ test_multichars
|
|||
|
||||
ucs4_utf8 = (char *)malloc(len);
|
||||
|
||||
len = 0;
|
||||
len = 1;
|
||||
for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
|
||||
ucs2s[i] = ucs2[i].c;
|
||||
len += strlen(ucs2[i].utf8);
|
||||
|
@ -1781,6 +1850,7 @@ main
|
|||
test_ucs2_chars() &&
|
||||
test_utf16_chars() &&
|
||||
test_utf8_bad_chars() &&
|
||||
test_utf16_bad_chars() &&
|
||||
test_iso88591_chars() &&
|
||||
test_zeroes() &&
|
||||
test_multichars() &&
|
||||
|
|
Loading…
Reference in New Issue