more integer conversions working
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index a061dc6..4257f10 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2637,20 +2637,18 @@
return uReturn;
}
- // Error out if too large on the plus side for an int64_t
- if(uResult > INT64_MAX) {
- return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
- }
- // Error out if too large on the negative side for an int64_t
- if(uResult < (uint64_t)INT64_MAX+1) {
- /* (uint64_t)INT64_MAX+1 is used to represent the absolute value
- of INT64_MIN. This assumes two's compliment representation where
- INT64_MIN is one increment farther from 0 than INT64_MAX.
- Trying to write -INT64_MIN doesn't work to get this because the
- compiler tries to work with an int64_t which can't represent
- -INT64_MIN.
- */
+ /* (uint64_t)INT64_MAX+1 is used to represent the absolute value
+ of INT64_MIN. This assumes two's compliment representation where
+ INT64_MIN is one increment farther from 0 than INT64_MAX.
+ Trying to write -INT64_MIN doesn't work to get this because the
+ compiler tries to work with an int64_t which can't represent
+ -INT64_MIN.
+ */
+ uint64_t uMax = nMantissa > 0 ? INT64_MAX : (uint64_t)INT64_MAX+1;
+
+ // Error out if too large
+ if(uResult > uMax) {
return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
}
@@ -2751,11 +2749,11 @@
dResult = 0.0;
const uint8_t *pByte = BigNum.ptr;
size_t uLen = BigNum.len;
- /* This will overflow and become the float value INFINITY if the number
+ /* This will overflow and become the float value INFINITY if the number
is too large to fit. No error will be logged.
TODO: should an error be logged? */
while(uLen--) {
- dResult = (dResult * 256.0) + *pByte;
+ dResult = (dResult * 256.0) + (double)*pByte;
}
return dResult;
@@ -3140,7 +3138,7 @@
case QCBOR_TYPE_NEGBIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
- pMe->uLastError = (uint8_t)ConvertPositiveBigNumToUnSigned(Item.val.bigNum, pValue);
+ pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
}
@@ -3189,14 +3187,7 @@
case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- int64_t nMantissa;
- pMe->uLastError = (uint8_t)ConvertNegativeBigNumToSigned(Item.val.expAndMantissa.Mantissa.bigNum, &nMantissa);
- if(!pMe->uLastError) {
- pMe->uLastError = (uint8_t)ExponentitateNU(nMantissa,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate10UU);
- }
+ pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED; // TODO: error code
}
@@ -3219,14 +3210,7 @@
case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- int64_t nMantissa;
- pMe->uLastError = (uint8_t)ConvertNegativeBigNumToSigned(Item.val.expAndMantissa.Mantissa.bigNum, &nMantissa);
- if(!pMe->uLastError) {
- pMe->uLastError = (uint8_t)ExponentitateNU(nMantissa,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate2UU);
- }
+ pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
}
@@ -3286,7 +3270,7 @@
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
}
-
+ break;
case QCBOR_TYPE_DECIMAL_FRACTION:
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
@@ -3336,28 +3320,28 @@
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
double dMantissa = -ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
*pValue = dMantissa * pow(10, (double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
+ } else {
+ pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
case QCBOR_TYPE_BIGFLOAT_POS_BIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
double dMantissa = ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
*pValue = dMantissa * exp2((double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
+ } else {
+ pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
double dMantissa = -ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
*pValue = dMantissa * exp2((double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
+ } else {
+ pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
}
}
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 31d495c..0d630b6 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -4002,6 +4002,48 @@
static struct NumberConversion NumberConversions[] = {
{
+ "Big float 3 * 2^^2",
+ {(uint8_t[]){0xC5, 0x82, 0x02, 0x03}, 4},
+ 12,
+ QCBOR_SUCCESS,
+ 12,
+ QCBOR_SUCCESS,
+ 12.0,
+ QCBOR_SUCCESS
+ },
+ // | 18446744073709551615 | 0x1bffffffffffffffff
+ {
+ "18446744073709551615",
+ {(uint8_t[]){0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 9},
+ 0,
+ QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW,
+ 18446744073709551615ULL,
+ QCBOR_SUCCESS,
+ 18446744073709551615.0,
+ QCBOR_SUCCESS
+ },
+
+ /* {
+ "negative bignum 0xc349010000000000000000",
+ {(uint8_t[]){0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 11},
+ 0,
+ QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW,
+ 0,
+ QCBOR_ERR_NUMBER_SIGN_CONVERSION,
+ -18446744073709551617.0,
+ QCBOR_SUCCESS
+ }, */
+ {
+ "positive bignum 0xffff",
+ {(uint8_t[]){0xC2, 0x42, 0xff, 0xff}, 4},
+ 65536-1,
+ QCBOR_SUCCESS,
+ 0xffff,
+ QCBOR_SUCCESS,
+ 65535.0,
+ QCBOR_SUCCESS
+ },
+ {
"Postive integer 0",
{(uint8_t[]){0x0}, 1},
0LL,
@@ -4121,6 +4163,8 @@
}
if(pF->uErrorDouble == QCBOR_SUCCESS) {
if(isnan(pF->dConvertToDouble)) {
+ // NaN's can't be compared for equality. A NaN is
+ // never equal to anything including another NaN
if(!isnan(d)) {
return -4;
}