Skip to content

Commit d940ae9

Browse files
laurencelundbladeLaurence Lundblade
andauthored
GetNextTagNumber() fix
Fixes a bug in GetNextTagNumber() that occurs when trying to get all tag numbers for an item in loop. Improves tag number testing. * Fix bug with GetNextTagNumber() * Improve tests * Fix compiler warnings --------- Co-authored-by: Laurence Lundblade <[email protected]>
1 parent aa7e30c commit d940ae9

File tree

3 files changed

+137
-77
lines changed

3 files changed

+137
-77
lines changed

inc/qcbor/qcbor_tag_decode.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ QCBORDecode_GetNextTagNumberInMapSZ(QCBORDecodeContext *pCtx, const char *szLabe
272272
* Normally, tag numbers are processed QCBORDecode_VGetNextTagNumber() or
273273
* QCBORTagContentCallBack.
274274
*
275+
* TODO: rewrite this paragraph
276+
* TODO: are tag not fetched by QCBORDecode_VGetNextTagNumber put here?
275277
* When QCBOR decodes an item that is a tag, it will fully decode tags
276278
* it is able to. Tags that it is unable to process are put in a list
277279
* in the QCBORItem.
@@ -291,7 +293,7 @@ QCBORDecode_GetNextTagNumberInMapSZ(QCBORDecodeContext *pCtx, const char *szLabe
291293
* See also @ref TagDecoding @ref CBORTags.
292294
*
293295
* To reduce memory used by a @ref QCBORItem, tag numbers larger than
294-
* @c UINT16_MAX are mapped so the tag numbers in @c uTags should be
296+
* @c UINT16_MAX are mapped so the tag numbers in @c auTagNumbers must be
295297
* accessed with this function rather than directly.
296298
*
297299
* This returns @ref CBOR_TAG_INVALID64 if any error occurred when
@@ -1121,7 +1123,7 @@ QCBORDecode_ExpMantissaTagCB(QCBORDecodeContext *pDecodeCtx,
11211123
#ifndef QCBOR_DISABLE_TAGS
11221124

11231125
/**
1124-
* @brief [Deprecated] Returns the tag numbers for an item..
1126+
* @brief [Deprecated] Returns the tag numbers for an item.
11251127
* @deprecated Use QCBORDecode_GetNthTagNumber() instead.
11261128
*
11271129
* @param[in] pCtx The decoder context.

src/qcbor_tag_decode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ QCBORDecode_GetNextTagNumber(QCBORDecodeContext *pMe, uint64_t *puTagNumber)
3333

3434
uOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
3535
if(uOffset == pMe->uTagNumberCheckOffset) {
36-
pMe->uTagNumberIndex++;
36+
if(pMe->uTagNumberIndex != QCBOR_ALL_TAGS_PROCESSED) {
37+
pMe->uTagNumberIndex++;
38+
}
3739
} else {
3840
pMe->uTagNumberIndex = 0;
3941
}

test/qcbor_decode_tests.c

Lines changed: 130 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3987,6 +3987,84 @@ int32_t SpiffyDateDecodeTest(void)
39873987

39883988

39893989
#ifndef QCBOR_DISABLE_TAGS
3990+
3991+
3992+
struct TestInput {
3993+
const char *szDescription;
3994+
UsefulBufC EncodedCBOR;
3995+
};
3996+
3997+
3998+
/* Tests don't lend themselves to iteration over this,
3999+
* but still nice to organize into an array with descriptions. */
4000+
static const struct TestInput spTagInput2[] = {
4001+
/* 0 */
4002+
{"55799([4([1, 3])]), CBOR magic number in front of decimal fraction",
4003+
{
4004+
(uint8_t[]){0xd9, 0xd9, 0xf7, // CBOR magic number
4005+
0x81, // Array of one
4006+
0xd8, 0x04, // non-preferred serialization of tag 4, decimal fraction
4007+
0x82, // Array of two that is the faction 1/3
4008+
0x01,
4009+
0x03}, 9},
4010+
},
4011+
4012+
/* 1 */
4013+
{"More than 4 tags on an item 225(226(227(228(229([])))))",
4014+
{
4015+
(uint8_t[]) {0xd8, 0xe1,
4016+
0xd8, 0xe2,
4017+
0xd8, 0xe3,
4018+
0xd8, 0xe4,
4019+
0xd8, 0xe5,
4020+
0x80}, 11},
4021+
},
4022+
4023+
/* 2 */
4024+
{"10489608748473423768( 2442302356( 21590( 240([]))))",
4025+
{
4026+
(uint8_t[]) {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
4027+
0xda, 0x91, 0x92, 0x93, 0x94,
4028+
0xd9, 0x54, 0x56,
4029+
0xd8, 0xf0,
4030+
0x80}, 20},
4031+
},
4032+
4033+
/* 3 */
4034+
{"21590(10489608748473423768(2442302357(65534([]))))",
4035+
{
4036+
(uint8_t[]) {0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x56,
4037+
0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
4038+
0xda, 0x91, 0x92, 0x93, 0x95,
4039+
0xd9, 0xff, 0xfe,
4040+
0x80}, 27},
4041+
},
4042+
4043+
/* 4 */
4044+
{"More than 4 tags 269488144( 269488145( 269488146( 269488147( 269488148([])))))",
4045+
{
4046+
(uint8_t[]) {0xda, 0x10, 0x10, 0x10, 0x10,
4047+
0xda, 0x10, 0x10, 0x10, 0x11,
4048+
0xda, 0x10, 0x10, 0x10, 0x12,
4049+
0xda, 0x10, 0x10, 0x10, 0x13,
4050+
0xda, 0x10, 0x10, 0x10, 0x14,
4051+
0x80}, 26},
4052+
},
4053+
4054+
/* 5 */
4055+
{"An invalid decimal fraction with an additional tag",
4056+
{
4057+
(uint8_t[]) {0xd9, 0xff, 0xfa,
4058+
0xd8, 0x02,
4059+
0x00}, 6},
4060+
},
4061+
4062+
{NULL,
4063+
NULLUsefulBufC}
4064+
};
4065+
4066+
4067+
39904068
// Input for one of the tagging tests
39914069
static const uint8_t spTagInput[] = {
39924070
0xd9, 0xd9, 0xf7, // CBOR magic number
@@ -4274,16 +4352,11 @@ int32_t TagNumberDecodeTest(void)
42744352
return -10;
42754353
}
42764354

4277-
/* Testing with v2 */
4278-
QCBORDecode_Init(&DCtx,
4279-
UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTagInput),
4280-
QCBOR_DECODE_MODE_NORMAL);
42814355

4282-
/*
4283-
This test matches the magic number tag and the fraction tag
4284-
55799([...])
4285-
*/
4356+
/* V2 tag mode testing */
42864357
uint64_t uTagNumber;
4358+
4359+
QCBORDecode_Init(&DCtx, spTagInput2[0].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
42874360
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
42884361
if(uError != QCBOR_SUCCESS) {
42894362
return -200;
@@ -4303,109 +4376,92 @@ int32_t TagNumberDecodeTest(void)
43034376
return -500;
43044377
}
43054378

4306-
4307-
4308-
/*
4309-
4([1,3])
4310-
*/
4311-
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4312-
if(uError != QCBOR_SUCCESS) {
4313-
return -200;
4314-
}
4315-
if(uTagNumber != CBOR_TAG_DECIMAL_FRACTION) {
4316-
return -300;
4317-
}
4318-
4319-
4320-
uError = QCBORDecode_GetNext(&DCtx, &Item);
4321-
if(uError != QCBOR_SUCCESS ||
4322-
Item.uDataType != QCBOR_TYPE_ARRAY ||
4323-
QCBORDecode_GetNthTag(&DCtx, &Item, 0) != CBOR_TAG_DECIMAL_FRACTION ||
4324-
QCBORDecode_GetNthTag(&DCtx, &Item, 1) != CBOR_TAG_INVALID64 ||
4325-
QCBORDecode_GetNthTag(&DCtx, &Item, 2) != CBOR_TAG_INVALID64 ||
4326-
QCBORDecode_GetNthTag(&DCtx, &Item, 3) != CBOR_TAG_INVALID64 ||
4327-
QCBORDecode_GetNthTag(&DCtx, &Item, 4) != CBOR_TAG_INVALID64 ||
4328-
Item.val.uCount != 2) {
4329-
return -4;
4330-
}
4331-
// consume the items in the array
4332-
uError = QCBORDecode_GetNext(&DCtx, &Item);
4333-
uError = QCBORDecode_GetNext(&DCtx, &Item);
4334-
4335-
4336-
/*
4337-
More than 4 tags on an item 225(226(227(228(229([])))))
4338-
*/
4379+
/* More than 4 tag numbers */
4380+
QCBORDecode_Init(&DCtx, spTagInput2[1].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
43394381
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
43404382
if(uError != QCBOR_ERR_TOO_MANY_TAGS) {
43414383
return -2;
43424384
}
43434385

4344-
4345-
/* tag 10489608748473423768(
4346-
2442302356(
4347-
21590(
4348-
240(
4349-
[]))))
4350-
*/
4386+
/* An array with for big tag numbers on it */
4387+
QCBORDecode_Init(&DCtx, spTagInput2[2].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
43514388
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4352-
if(uError != QCBOR_SUCCESS || uTagNumber != 10489608748473423768ULL) {
4353-
return -6;
4389+
if(uError != QCBOR_SUCCESS || uTagNumber != 10489608748473423768ULL) {
4390+
return -81;
43544391
}
43554392
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
43564393
if(uError != QCBOR_SUCCESS || uTagNumber != 2442302356ULL) {
4357-
return -6;
4394+
return -81;
43584395
}
43594396
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
43604397
if(uError != QCBOR_SUCCESS || uTagNumber != 21590ULL) {
4361-
return -6;
4398+
return -81;
43624399
}
43634400
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
43644401
if(uError != QCBOR_SUCCESS || uTagNumber != 240ULL) {
4365-
return -6;
4402+
return -81;
43664403
}
43674404
uError = QCBORDecode_GetNext(&DCtx, &Item);
4368-
if(uError != QCBOR_SUCCESS) {
4369-
return -2;
4370-
}
4371-
if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.val.uCount != 0) {
4372-
return -1003;
4405+
if(uError != QCBOR_SUCCESS || Item.uDataType != QCBOR_TYPE_ARRAY) {
4406+
return -81;
43734407
}
43744408

4375-
/* tag 21590(
4376-
10489608748473423768(
4377-
2442302357(
4378-
21591(
4379-
[]))))
4380-
*/
4409+
4410+
/* Decode the four tag numbers and see success */
4411+
QCBORDecode_Init(&DCtx, spTagInput2[3].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
43814412
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4413+
if(uError != QCBOR_SUCCESS || uTagNumber != 21590ULL) {
4414+
return -81;
4415+
}
43824416
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4417+
if(uError != QCBOR_SUCCESS || uTagNumber != 10489608748473423768ULL) {
4418+
return -81;
4419+
}
43834420
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4421+
if(uError != QCBOR_SUCCESS || uTagNumber != 2442302357ULL) {
4422+
return -81;
4423+
}
43844424
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4385-
4425+
if(uError != QCBOR_SUCCESS || uTagNumber != 65534ULL) {
4426+
return -81;
4427+
}
43864428
uError = QCBORDecode_GetNext(&DCtx, &Item);
43874429
if(uError != QCBOR_SUCCESS ||
43884430
Item.uDataType != QCBOR_TYPE_ARRAY ||
4389-
QCBORDecode_GetNthTag(&DCtx, &Item, 0) != 65534ULL ||
4390-
QCBORDecode_GetNthTag(&DCtx, &Item, 1) != 2442302357ULL ||
4391-
QCBORDecode_GetNthTag(&DCtx, &Item, 2) != 10489608748473423768ULL ||
4392-
QCBORDecode_GetNthTag(&DCtx, &Item, 3) != 21590ULL) {
4431+
QCBORDecode_GetNthTagNumber(&DCtx, &Item, 3) != 65534ULL ||
4432+
QCBORDecode_GetNthTagNumber(&DCtx, &Item, 2) != 2442302357ULL ||
4433+
QCBORDecode_GetNthTagNumber(&DCtx, &Item, 1) != 10489608748473423768ULL ||
4434+
QCBORDecode_GetNthTagNumber(&DCtx, &Item, 0) != 21590ULL) {
43934435
return -8;
43944436
}
43954437

4396-
/* Make sure to blow past the limit of tags that must be mapped.
4397-
works in conjuntion with entries above.
4398-
269488144(269488145(269488146(269488147([]))))
4399-
*/
4438+
/* As above, but ask for a 5th tag number */
4439+
QCBORDecode_Init(&DCtx, spTagInput2[3].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
4440+
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4441+
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4442+
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
44004443
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4444+
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
4445+
if(uError != QCBOR_SUCCESS || uTagNumber != CBOR_TAG_INVALID64) {
4446+
return -7;
4447+
}
4448+
4449+
/* More than 4 tags. Even with v2 processing, there is a max of 4 tags. */
4450+
/* (Perhaps v2 processing will be different someday and not have this limit. */
4451+
QCBORDecode_Init(&DCtx, spTagInput2[4].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
4452+
uError = QCBORDecode_GetNext(&DCtx, &Item);
44014453
if(uError != QCBOR_ERR_TOO_MANY_TAGS) {
44024454
return -9;
44034455
}
44044456

4405-
uError = QCBORDecode_GetNext(&DCtx, &Item);
4457+
/* The input is a bad decimal frac with extra tag number */
4458+
QCBORDecode_Init(&DCtx, spTagInput2[5].EncodedCBOR, QCBOR_DECODE_MODE_NORMAL);
4459+
QCBORDecode_InstallTagDecoders(&DCtx, QCBORDecode_TagDecoderTablev1, NULL);
4460+
uError = QCBORDecode_GetNextTagNumber(&DCtx, &uTagNumber);
44064461
if(uError == QCBOR_SUCCESS) {
44074462
return -10;
44084463
}
4464+
// 65530
44094465
/* 0-0-0-0-0-0-0--0-0--0*/
44104466

44114467

0 commit comments

Comments
 (0)