bstr wrap code progressing
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index bd35728..114724d 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -139,8 +139,7 @@
"hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
the call to QCBOREncode_AddBytes(). */
#define CBOR_TAG_ENC_AS_B16 23
-/** Tag to indicate a byte string contains encoded CBOR. No API is
- provided for this tag. */
+/** See QCBORDecode_EnterWrappedBstr(). */
#define CBOR_TAG_CBOR 24
/** See QCBOREncode_AddURI(). */
#define CBOR_TAG_URI 32
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 5da7ba3..a4b4dfe 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -254,6 +254,8 @@
#define QCBOR_TYPE_BASE64 38
+#define QBCOR_TYPE_WRAPPED_CBOR 39
+
#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
@@ -1145,7 +1147,6 @@
*/
static void QCBORDecode_GetUInt64(QCBORDecodeContext *pCtx, uint64_t *puValue);
-
static void QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint64_t *puValue);
static void QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint64_t *puValue);
@@ -1583,13 +1584,53 @@
static void QCBORDecode_ExitArray(QCBORDecodeContext *pCtx);
+
+/*
+
+
+
+ This is for use on some CBOR that has been wrapped in a
+ byte string. There are several ways that this can occur.
+
+ First is tag 24 and tax XXX (soon to be defined). Tag 24
+ wraps a single CBOR data item and XXX a CBOR sequence.
+ This implementation doesn't distinguish between the two
+ (it would be more code and doesn't seem important).
+
+ The XYZ discussion on the tag requirement applies here
+ just the same as any other tag.
+
+ In other cases, CBOR is wrapped in a byte string, but
+ it is identified as CBOR by other means. The contents
+ of a COSE payload are one example of that. They can
+ be identified by the COSE content type, or they can
+ be identified as CBOR indirectly by the protocol that
+ uses COSE. In particular if a blob of CBOR is identified
+ as a CWT, then the COSE payload is CBOR.
+
+ To enter into CBOR of this type use the
+ \ref QCBOR_WRAP as the \c uTagRequirement argument.
+
+ Note that byte string wrapped CBOR can also be
+ decoded by getting the byte string with QCBORDecode_GetItem() or
+ QCBORDecode_GetByteString() and feeding it into another
+ instance of QCBORDecode. Doing it with this function
+ has the advantage of using less memory as another
+ instance of QCBORDecode is not necessary.
+
+ When the wrapped CBOR is entered with this function,
+ the pre-order traversal and such are bounded to
+ the wrapped CBOR. QCBORDecode_ExitBstrWrapped()
+ must be called resume processing CBOR outside
+ the wrapped CBOR.
+ */
void QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pCtx,
uint8_t uTagRequirement,
UsefulBufC *pBstr);
void QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pCtx,
uint8_t uTagRequirement,
- int64_t uLabel,
+ int64_t nLabel,
UsefulBufC *pBstr);
void QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pCtx,
@@ -1604,6 +1645,7 @@
/*
+ TODO: fix this
Restarts fetching of items in a map to the start of the
map. This is for GetNext. It has no effect on
GetByLabel (which always searches from the start).
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 6ccef67..05059e4 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -1600,6 +1600,14 @@
return QCBOR_SUCCESS;
}
+inline static QCBORError DecodeWrappedCBOR(QCBORItem *pDecodedItem)
+{
+ if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+ return QCBOR_ERR_BAD_OPT_TAG;
+ }
+ pDecodedItem->uDataType = QBCOR_TYPE_WRAPPED_CBOR;
+ return QCBOR_SUCCESS;
+}
inline static QCBORError DecodeMIME(QCBORItem *pDecodedItem)
{
@@ -1666,6 +1674,10 @@
break;
#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
+ case CBOR_TAG_CBOR:
+ nReturn = DecodeWrappedCBOR(pDecodedItem);
+ break;
+
case CBOR_TAG_URI:
nReturn = DecodeURI(pDecodedItem);
break;
@@ -2713,7 +2725,50 @@
-void QCBORDecode_EnterBstr(QCBORDecodeContext *pMe)
+static QCBORError FarfWrappedBstr(QCBORDecodeContext *pMe, const QCBORItem *pItem, uint8_t uTagRequirement, UsefulBufC *pBstr)
+{
+ if(pMe->uLastError != QCBOR_SUCCESS) {
+ // Already in error state; do nothing.
+ return pMe->uLastError;
+ }
+
+ QCBORError uError = QCBOR_SUCCESS;
+
+ if(pItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+ uError = QCBOR_ERR_UNEXPECTED_TYPE;
+ goto Done;;
+ }
+
+ // TODO: check for the other wrapped CBOR
+ const TagSpecification TagSpec = {uTagRequirement, QBCOR_TYPE_WRAPPED_CBOR, {QCBOR_TYPE_BYTE_STRING, 0,0,0,0,0}};
+
+ uError = CheckTagRequirement(TagSpec, pItem->uDataType);
+ if(uError != QCBOR_SUCCESS) {
+ goto Done;
+ }
+
+ *pBstr = pItem->val.string;
+
+ // Need to move UIB input cursor to the right place
+
+ // Really this is a subtraction and an assignment; not much code
+ // There is a range check in the seek.
+ const size_t uEndOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
+
+ UsefulInputBuf_Seek(&(pMe->InBuf), uEndOffset - pItem->val.string.len);
+
+ UsefulInputBuf_SetBufferLen(&(pMe->InBuf), uEndOffset);
+
+ // TODO: comment on cast
+ uError = DecodeNesting_Descend(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING, UINT16_MAX, (uint32_t)uEndOffset);
+
+Done:
+ return uError;
+
+}
+
+
+void QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pMe, uint8_t uTagRequirement, UsefulBufC *pBstr)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
// Already in error state; do nothing.
@@ -2726,44 +2781,32 @@
if(pMe->uLastError != QCBOR_SUCCESS) {
return;
}
- if(Item.uDataType != QCBOR_TYPE_BYTE_STRING) {
- pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
- return;
- }
- // TODO: check for tag 24
-
- // Need to move UIB input cursor to the right place
-
- // Really this is a subtraction and an assignment; not much code
- // There is a range check in the seek.
- const size_t uEndOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
-
- UsefulInputBuf_Seek(&(pMe->InBuf), uEndOffset - Item.val.string.len);
-
- UsefulInputBuf_SetBufferLen(&(pMe->InBuf), uEndOffset);
-
- // TODO: comment on cast
- pMe->uLastError = (uint8_t)DecodeNesting_Descend(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING, UINT16_MAX, (uint32_t)uEndOffset);
+ pMe->uLastError = (uint8_t)FarfWrappedBstr(pMe, &Item, uTagRequirement, pBstr);
}
-void QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pMe, uint8_t uTagRequirement, UsefulBufC *pBstr)
+void QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pMe, uint8_t uTagRequirement, int64_t nLabel, UsefulBufC *pBstr)
{
QCBORItem Item;
- QCBORDecode_GetNext(pMe, &Item);
- // Need to set UIB cursor to start of bstr and UIB length to end of bstr
-
- // TODO: combine with above
+ QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+ pMe->uLastError = (uint8_t)FarfWrappedBstr(pMe, &Item, uTagRequirement, pBstr);
}
-//void QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pCtx, int64_t uLabel, UsefulBufC *pBstr);
-//void QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, UsefulBufC *pBstr);
+void QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pMe, uint8_t uTagRequirement, const char *szLabel, UsefulBufC *pBstr)
+{
+ QCBORItem Item;
+ QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+
+ pMe->uLastError = (uint8_t)FarfWrappedBstr(pMe, &Item, uTagRequirement, pBstr);
+
+}
void QCBORDecode_ExitBstrWrapped(QCBORDecodeContext *pCtx)
{
+ // TODO: write this code
// Need to set the cursor to end of the bstr and length to the next length
// above in the nesting tree (or the top level length).
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 2665ac3..3a21720 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2857,7 +2857,6 @@
}
-// TODO: investigate why this doesn't fail in master and does here. It seems like a broken test.
int32_t IndefiniteLengthNestTest()
{
UsefulBuf_MAKE_STACK_UB(Storage, 50);