| Index: nss/lib/util/dersubr.c
|
| diff --git a/nss/lib/util/dersubr.c b/nss/lib/util/dersubr.c
|
| index 0f4c6d95c4331848fe1d7cd2ed4c4b2880eb37c7..657dd9f0139d5e57470bc49b280e813e25af5d87 100644
|
| --- a/nss/lib/util/dersubr.c
|
| +++ b/nss/lib/util/dersubr.c
|
| @@ -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;
|
| }
|
|
|
|
|