test and documentation
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 82ea6c0..f0b8d0e 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -1774,13 +1774,21 @@
/**
- @brief Cancel a wrapping bstr.
-
- @param[in] pCtx The encoding context to close of bstr wrapping in.
-
- This only works if nothing has been added into the wrapped byte string.
- If something has been added, this sets the TODO: error.
- **/
+ * @brief Cancel byte string wrapping.
+ *
+ * @param[in] pCtx The encoding context to close of bstr wrapping in.
+ *
+ * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
+ * were never called.
+ *
+ * WARNING: This does no work on QCBOREncode_BstrWrapInMap()
+ * or QCBOREncode_BstrWrapInMapN() and there is no detection
+ * of this error.
+ *
+ * This only works if nothing has been added into the wrapped byte
+ * string. If something has been added, this sets the error
+ * @ref QCBOR_ERR_CANNOT_CANCEL.
+ */
void QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 9c286a9..ea94026 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -918,6 +918,14 @@
return;
}
}
+ /* QCBOREncode_CancelBstrWrap() can't correctly undo
+ * QCBOREncode_BstrWrapInMap() or QCBOREncode_BstrWrapInMapN(). It
+ * can't undo the labels they add. It also doesn't catch the error
+ * of using it this way. QCBOREncode_CancelBstrWrap() is used
+ * infrequently and the the result is incorrect CBOR, not a
+ * security hole, so no extra code or state is added to handle this
+ * condition.
+ */
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
Nesting_Decrease(&(pMe->nesting));
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 99dd7b7..d2f9958 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -1746,8 +1746,9 @@
static const uint8_t spExpectedTypeAndLen[] = {0x81, 0x58, 0x25};
static const uint8_t spExpectedTypeAndLenXXX[] = {0x82, 0x19, 0x01, 0xC3, 0x18, 0x2A};
+
/*
- Very basic bstr wrapping test
+ * bstr wrapping test
*/
int BstrWrapTest()
{
@@ -1807,7 +1808,6 @@
return -7;
}
-
// Fourth test, cancelling a byte string
QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -1827,6 +1827,8 @@
return -9;
}
+ QCBORError uErr;
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
// Fifth test, failed cancelling
QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -1839,10 +1841,29 @@
QCBOREncode_AddUInt64(&EC, 42);
QCBOREncode_CloseArray(&EC);
- QCBORError uErr = QCBOREncode_Finish(&EC, &Encoded);
+ uErr = QCBOREncode_Finish(&EC, &Encoded);
if(uErr != QCBOR_ERR_CANNOT_CANCEL) {
return -10;
}
+#endif
+
+ // Sixth test, another cancel, but the error is not caught
+ // This use will produce unintended CBOR. The error
+ // is not caught because it would require tracking state
+ // for QCBOREncode_BstrWrapInMapN.
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+
+ QCBOREncode_OpenMap(&EC);
+ QCBOREncode_AddUInt64ToMapN(&EC, 451, 88);
+
+ QCBOREncode_BstrWrapInMapN(&EC, 55);
+ QCBOREncode_CancelBstrWrap(&EC);
+
+ QCBOREncode_CloseMap(&EC);
+ uErr = QCBOREncode_Finish(&EC, &Encoded);
+ if(uErr != QCBOR_SUCCESS) {
+ return -11;
+ }
return 0;
}