date decoding fixes and tests
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 2d53f4b..d882d99 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2101,9 +2101,15 @@
0xc0, // tag for string date
0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
+ 0xc0, // tag for string date
+ 0x00, // Wrong type for a string date
+
0xc1, // tag for epoch date
0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+ 0xc1,
+ 0x62, 'h', 'i', // wrong type tagged
+
// CBOR_TAG_B64
0xc1, 0xcf, 0xd8, 0x22, // 0xee, // Epoch date with extra tags
0x1a, 0x53, 0x72, 0x4E, 0x01,
@@ -2122,10 +2128,20 @@
//0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
0xc1, // tag for epoch date
- 0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe // 9223372036854773760 largest supported
+ 0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, // 9223372036854773760 largest supported
+
+ 0xc1, // tag for epoch date
+ 0xfa, 0x7f, 0xc0, 0x00, 0x00, // Single-precision NaN
+
+ 0xc1,
+ 0xfb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // +infinity
+
+ 0xc1, // tag for epoch date
+ 0xf9, 0xfc, 0x00, // -Infinity
};
+
// have to check float expected only to within an epsilon
#ifndef QCBOR_DISABLE_FLOAT_HW_USE
static int CHECK_EXPECTED_DOUBLE(double val, double expected) {
@@ -2142,69 +2158,79 @@
int32_t DateParseTest()
{
QCBORDecodeContext DCtx;
- QCBORItem Item;
- QCBORError nCBORError;
+ QCBORItem Item;
+ QCBORError uError;
QCBORDecode_Init(&DCtx,
UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput),
QCBOR_DECODE_MODE_NORMAL);
- const uint64_t uTags[] = {15};
- QCBORTagListIn TagList = {1, uTags};
-
- QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
-
// String date
- if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+ if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
return -1;
+ }
if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
return -2;
}
- // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
- if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+ // Wrong type for a string date
+ uError = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uError != QCBOR_ERR_BAD_OPT_TAG) {
return -3;
+ }
+
+ // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+ if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return -4;
+ }
if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
Item.val.epochDate.nSeconds != 1400000000 ||
Item.val.epochDate.fSecondsFraction != 0 ) {
- return -4;
+ return -5;
+ }
+
+ // Wrong type for an epoch date
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_OPT_TAG) {
+ return -6;
}
// Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
// but want to be sure extra tag doesn't cause a problem
- if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
- return -5;
+ if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return -7;
+ }
if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
Item.val.epochDate.nSeconds != 1400000001 ||
Item.val.epochDate.fSecondsFraction != 0 ||
!QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
- return -6;
+ return -8;
}
// Epoch date that is too large for our representation
if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
- return -7;
+ return -9;
}
- // Epoch date in float format with fractional seconds
#ifndef QCBOR_DISABLE_FLOAT_HW_USE
- if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
- return -8;
+ // Epoch date in float format with fractional seconds
+ if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return -10;
+ }
if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
Item.val.epochDate.nSeconds != 1 ||
CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
- return -9;
+ return -11;
}
// Epoch date float that is too large for our representation
if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
- return -10;
+ return -12;
}
// Epoch date double that is just slightly too large
if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
- return -11;
+ return -13;
}
// Largest double epoch date supported
@@ -2212,30 +2238,188 @@
Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
Item.val.epochDate.nSeconds != 9223372036854773760 ||
Item.val.epochDate.nSeconds == 0) {
- return -12;
+ return -14;
}
+
+ // Nan
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+ return -15;
+ }
+
+ // +Inifinity double-precision
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+ return -16;
+ }
+
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+ // -Inifinity half-precision
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+ return -17;
+ }
#else
- if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
- return -80;
- }
- if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
- return -80;
- }
- if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
- return -80;
- }
- if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
- return -80;
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
+ return -18;
}
#endif
+#else
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -19;
+ }
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -20;
+ }
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -21;
+ }
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -22;
+ }
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -23;
+ }
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -24;
+ }
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+ return -25;
+ }
+#else
+ if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
+ return -26;
+ }
+#endif
- // TODO: could use a few more tests with float, double, and half precsion
- // and negative (but coverage is still pretty good)
+#endif
return 0;
}
+
+static uint8_t spDateTestInput2[] = {
+ 0xbf,
+
+ 0x05,
+ 0xc1, // tag for epoch date
+ 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
+
+ 0x00,
+ 0xc0, // tag for string date
+ 0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
+
+ 0x01,
+ 0xc1, // tag for epoch date
+ 0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+
+ // Untagged integer 0
+ 0x08,
+ 0x00,
+
+ // Utagged date string with string label y
+ 0x61, 0x79,
+ 0x6a, '2','0','8','5','-','0','4','-','1','2', // Date string
+
+ // Untagged -1000 with label z
+ 0x61, 0x7a,
+ 0x39, 0x03, 0xe7,
+
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+ 0x07,
+ 0xc1, // tag for epoch date
+ 0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, // 9223372036854773760 largest supported
+
+ // Untagged single-precision float with value 3.14 with string label x
+ 0x61, 0x78,
+ 0xFA, 0x40, 0x48, 0xF5, 0xC3,
+
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+ // Untagged half-precision float with value -2
+ 0x09,
+ 0xF9, 0xC0, 0x00,
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+ 0xff,
+};
+
+int32_t SpiffyDateDecodeTest()
+{
+ QCBORDecodeContext DC;
+ //QCBORItem Item;
+ QCBORError uError;
+ int64_t nEpochDate1, nEpochDate3, nEpochDate6;
+ UsefulBufC StringDate1, StringDate2;
+
+ QCBORDecode_Init(&DC,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput2),
+ QCBOR_DECODE_MODE_NORMAL);
+ QCBORDecode_EnterMap(&DC);
+ QCBORDecode_GetEpochDateInMapN(&DC, 5, QCBOR_TAG_REQUIREMENT_MATCH_TAG, &nEpochDate1);
+ uError = QCBORDecode_GetAndResetError(&DC);
+ if(uError == QCBOR_SUCCESS) {
+ return -999;
+ }
+ QCBORDecode_GetEpochDateInMapN(&DC, 1, QCBOR_TAG_REQUIREMENT_MATCH_TAG, &nEpochDate1);
+ QCBORDecode_GetDateStringInMapN(&DC, 0, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &StringDate1);
+ QCBORDecode_GetEpochDateInMapN(&DC, 8, QCBOR_TAG_REQUIREMENT_NO_TAG, &nEpochDate3);
+ QCBORDecode_GetDateStringInMapSZ(&DC, "y", QCBOR_TAG_REQUIREMENT_NO_TAG, &StringDate2);
+ QCBORDecode_GetEpochDateInMapSZ(&DC, "z", QCBOR_TAG_REQUIREMENT_NO_TAG, &nEpochDate6);
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+ int64_t nEpochDate5, nEpochDate2;
+ QCBORDecode_GetEpochDateInMapN(&DC, 7, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate2);
+ QCBORDecode_GetEpochDateInMapSZ(&DC, "x", QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate5);
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+ int64_t nEpochDate4;
+ QCBORDecode_GetEpochDateInMapN(&DC, 9, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate4);
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+ QCBORDecode_ExitMap(&DC);
+ uError = QCBORDecode_Finish(&DC);
+ if(uError) {
+ return 1;
+ }
+
+ if(nEpochDate1 != 1400000000) {
+ return 100;
+ }
+
+ if(nEpochDate3 != 0) {
+ return 102;
+ }
+
+ if(nEpochDate6 != -1000) {
+ return 105;
+ }
+
+ if(UsefulBuf_Compare(StringDate1, UsefulBuf_FromSZ("1985-04-12"))) {
+ return 106;
+ }
+
+ if(UsefulBuf_Compare(StringDate2, UsefulBuf_FromSZ("2085-04-12"))) {
+ return 107;
+ }
+
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+ if(nEpochDate2 != 9223372036854773760ULL) {
+ return 101;
+ }
+ if(nEpochDate5 != 3) {
+ return 104;
+ }
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+ if(nEpochDate4 != -2) {
+ return 103;
+ }
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+ return 0;
+}
+
+
+
// Really simple basic input for tagging test
static uint8_t spOptTestInput[] = {
0xd9, 0xd9, 0xf7, // CBOR magic number
@@ -4724,9 +4908,15 @@
if(Item.uDataType != QCBOR_TYPE_DATE_STRING) {
return 2;
}
-
+
// Get a second item
uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uCBORError != QCBOR_ERR_BAD_OPT_TAG) {
+ return 66;
+ }
+
+ // Get a third item
+ uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
if(uCBORError != QCBOR_SUCCESS) {
return 2;
}