New encode feature allows direct writing of byte string value (#137)
New features for UsefulBuf and for QCBOREncode allows direct writing to the output buffer. For QCBOREncode, this is the direct writing of the value of a byte string. This allows it to be written in chunks or be the output buffer of some function like symmetric encryption.
* fix grammer in security policy
* Half-way start a encoding feature to write byte string values into output
* Add documentation for OpenBstr
* UsefulBuf_Advance mostly working and testing
* OpenBytes() is mostly working and somewhat tested
* Finish up OpenBytes -- error handing, documentation...
Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index 1662fcc..e7f4d4f 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -1,6 +1,6 @@
/*============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Copyright (c) 2021, Arm Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
when who what, where, why
-------- ---- --------------------------------------------------
+ 4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf.
9/21/2021 llundbla Clarify UsefulOutBuf size calculation mode
8/8/2021 dthaler/llundbla Work with C++ without compiler extensions
5/11/2021 llundblade Improve comments and comment formatting.
@@ -1287,6 +1288,53 @@
/**
+ * @brief Returns pointer and length of the output buffer not yet used.
+ *
+ * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
+ *
+ * @return pointer and length of output buffer not used.
+ *
+ * This is an escape that allows the caller to write directly
+ * to the output buffer without any checks. This doesn't
+ * change the output buffer or state. It just returns a pointer
+ * and length of the bytes remaining.
+ *
+ * This is useful to avoid having the bytes to be added all
+ * in a contiguous buffer. Its use can save memory. A good
+ * example is in the COSE encrypt implementation where
+ * the output of the symmetric cipher can go directly
+ * into the output buffer, rather than having to go into
+ * an intermediate buffer.
+ *
+ * See UsefulOutBuf_Advance() which is used to tell
+ * UsefulOutBuf how much was written.
+ *
+ * Warning: this bypasses the buffer safety provided by
+ * UsefulOutBuf!
+ */
+static inline UsefulBuf
+UsefulOutBuf_GetOutPlace(UsefulOutBuf *pUOutBuf);
+
+
+/**
+ * @brief Advance the amount output assuming it was written by the caller.
+ *
+ * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
+ * @param[in] uAmount The amount to advance.
+ *
+ * This advances the position in the output buffer
+ * by \c uAmount. This assumes that the
+ * caller has written \c uAmount to the pointer obtained
+ * with UsefulOutBuf_GetOutPlace().
+ *
+ * Warning: this bypasses the buffer safety provided by
+ * UsefulOutBuf!
+ */
+void
+UsefulOutBuf_Advance(UsefulOutBuf *pUOutBuf, size_t uAmount);
+
+
+/**
* @brief Returns the resulting valid data in a UsefulOutBuf
*
* @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
@@ -2132,6 +2180,22 @@
}
+static inline UsefulBuf UsefulOutBuf_GetOutPlace(UsefulOutBuf *pUOutBuf)
+{
+ UsefulBuf R;
+
+ R.len = UsefulOutBuf_RoomLeft(pUOutBuf);
+ if(R.len > 0) {
+ R.ptr = (uint8_t *)pUOutBuf->UB.ptr + pUOutBuf->data_len;
+ } else {
+ R.ptr = NULL;
+ }
+
+ return R;
+}
+
+
+
static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
{
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index b9353b7..6c95c4b 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Copyright (c) 2021, Arm Limited.
All rights reserved.
@@ -314,7 +314,8 @@
QCBOR_ERR_TOO_MANY_CLOSES = 7,
/** During encoding the number of array or map opens was not
- matched by the number of closes. */
+ matched by the number of closes. Also occurs with opened
+ byte strings that are not closed. */
QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 8,
#define QCBOR_START_OF_NOT_WELL_FORMED_ERRORS 9
@@ -489,7 +490,7 @@
non-CBOR reason */
QCBOR_ERR_CALLBACK_FAIL = 38,
- /** This error code is deprecated. Instead,
+ /** This error code is deprecated. Instead,
\ref QCBOR_ERR_HALF_PRECISION_DISABLED,
\ref QCBOR_ERR_HW_FLOAT_DISABLED or \ref QCBOR_ERR_ALL_FLOAT_DISABLED
is returned depending on the specific floating-point functionality
@@ -524,7 +525,11 @@
/** Floating point support is completely turned off, encoding/decoding
floating point numbers is not possible. */
- QCBOR_ERR_ALL_FLOAT_DISABLED = 46
+ QCBOR_ERR_ALL_FLOAT_DISABLED = 46,
+
+ /** During encode, opening a byte string while a byte string is open
+ is not allowed. . */
+ QCBOR_ERR_OPEN_BYTE_STRING = 47
/* This is stored in uint8_t; never add values > 255 */
} QCBORError;
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 0abc594..8b2ed90 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -841,6 +841,62 @@
/**
+ @brief Set up to write a byte string value directly to encoded output.
+
+ @param[in] pCtx The encoding context to add the bytes to.
+ @param[out] pPlace Pointer and length of place to write byte string value.
+
+ QCBOREncode_AddBytes() is the normal way to encode a byte string.
+ This is for special cases and by passes some of the pointer safety.
+
+ The purpose of this is to output the bytes that make up a byte string
+ value directly to the QCBOR output buffer so you don't need to have a
+ copy of it in memory. This is particularly useful if the byte string
+ is large, for example, the encrypted payload of a COSE_Encrypt
+ message. The payload encryption algorithm can output directly to the
+ encoded CBOR buffer, perhaps by making it the output buffer
+ for some function (e.g. symmetric encryption) or by multiple writes.
+
+ The pointer in \c pPlace is where to start writing. Writing is just
+ copying bytes to the location by the pointer in \c pPlace. Writing
+ past the length in \c pPlace will be writing off the end of the
+ output buffer.
+
+ If there is no room in the output buffer @ref NULLUsefulBuf will be
+ returned and there is no need to call QCBOREncode_CloseBytes().
+
+ The byte string must be closed by calling QCBOREncode_CloseBytes().
+
+ Warning: this bypasses some of the usual checks provided by QCBOR
+ against writing off the end of the encoded output buffer.
+ */
+void
+QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
+
+static void
+QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBuf *pPlace);
+
+static void
+QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBuf *pPlace);
+
+
+/**
+ @brief Close out a byte string written directly to encoded output.
+
+ @param[in] pCtx The encoding context to add the bytes to.
+ @param[out] uAmount The number of bytes written, the length of the byte string.
+
+ This closes out a call to QCBOREncode_OpenBytes(). This inserts a
+ CBOR header at the front of the byte string value to make it a
+ well-formed byte string.
+
+ If there was no call to QCBOREncode_OpenBytes() then
+ @ref QCBOR_ERR_TOO_MANY_CLOSES is set.
+ */
+void QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
+
+
+/**
@brief Add a binary UUID to the encoded output.
@param[in] pCtx The encoding context to add the UUID to.
@@ -2371,6 +2427,20 @@
}
static inline void
+QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe, const char *szLabel, UsefulBuf *pPlace)
+{
+ QCBOREncode_AddSZString(pMe, szLabel);
+ QCBOREncode_OpenBytes(pMe, pPlace);
+}
+
+static inline void
+QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBuf *pPlace)
+{
+ QCBOREncode_AddInt64(pMe, nLabel);
+ QCBOREncode_OpenBytes(pMe, pPlace);
+}
+
+static inline void
QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
{
QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index 9f189e6..9a2a720 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -320,6 +320,8 @@
#define CBOR_MAJOR_NONE_TYPE_RAW 9
#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
+#define CBOR_MAJOR_NONE_TYPE_OPEN_BSTR 12
+
// Add this to types to indicate they are to be encoded as indefinite lengths
#define QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 0x80
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index e5be98a..f5149a5 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@
when who what, where, why
-------- ---- ---------------------------------------------------
+ 4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf
3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
01/28/2020 llundblade Refine integer signedness to quiet static analysis.
01/08/2020 llundblade Documentation corrections & improved code formatting.
@@ -304,6 +305,64 @@
/*
+ * Public function for advancing data length. See qcbor/UsefulBuf.h
+ */
+void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
+{
+ /* This function is a trimmed down version of
+ * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
+ * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
+ * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
+ * rarely used.
+ */
+
+ if(pMe->err) {
+ /* Already in error state. */
+ return;
+ }
+
+ /* 0. Sanity check the UsefulOutBuf structure
+ *
+ * A "counter measure". If magic number is not the right number it
+ * probably means me was not initialized or it was
+ * corrupted. Attackers can defeat this, but it is a hurdle and
+ * does good with very little code.
+ */
+ if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
+ pMe->err = 1;
+ return; /* Magic number is wrong due to uninitalization or corrption */
+ }
+
+ /* Make sure valid data is less than buffer size. This would only
+ * occur if there was corruption of me, but it is also part of the
+ * checks to be sure there is no pointer arithmatic
+ * under/overflow.
+ */
+ if(pMe->data_len > pMe->UB.len) { // Check #1
+ pMe->err = 1;
+ /* Offset of valid data is off the end of the UsefulOutBuf due
+ * to uninitialization or corruption.
+ */
+ return;
+ }
+
+ /* 1. Will it fit?
+ *
+ * WillItFit() is the same as: NewData.len <= (me->UB.len -
+ * me->data_len) Check #1 makes sure subtraction in RoomLeft will
+ * not wrap around
+ */
+ if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
+ /* The new data will not fit into the the buffer. */
+ pMe->err = 1;
+ return;
+ }
+
+ pMe->data_len += uAmount;
+}
+
+
+/*
Public function -- see UsefulBuf.h
*/
UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 7f9c169..af0e38b 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Copyright (c) 2021, Arm Limited.
All rights reserved.
@@ -541,6 +541,9 @@
}
}
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+ if(uMajorType == CBOR_MAJOR_NONE_TYPE_OPEN_BSTR) {
+ uMajorType = CBOR_MAJOR_TYPE_BYTE_STRING;
+ }
/* A stack buffer large enough for a CBOR head */
UsefulBuf_MAKE_STACK_UB(pBufferForEncodedHead, QCBOR_HEAD_BUFFER_SIZE);
@@ -932,6 +935,41 @@
/*
+ * Public function for opening a byte string. See qcbor/qcbor_encode.h
+ */
+void QCBOREncode_OpenBytes(QCBOREncodeContext *pMe, UsefulBuf *pPlace)
+{
+ *pPlace = UsefulOutBuf_GetOutPlace(&(pMe->OutBuf));
+ if(!UsefulBuf_IsNULL(*pPlace)){
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ uint8_t uMajorType = Nesting_GetMajorType(&(pMe->nesting));
+ if(uMajorType == CBOR_MAJOR_NONE_TYPE_OPEN_BSTR) {
+ pMe->uError = QCBOR_ERR_OPEN_BYTE_STRING;
+ return;
+ }
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+ QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR);
+ }
+}
+
+
+/*
+ * Public function for closing a byte string. See qcbor/qcbor_encode.h
+ */
+void QCBOREncode_CloseBytes(QCBOREncodeContext *pMe, const size_t uAmount)
+{
+ UsefulOutBuf_Advance(&(pMe->OutBuf), uAmount);
+ if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
+ /* Advance too far. Normal off-end error handling in effect here. */
+ return;
+ }
+
+ InsertCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR, uAmount);
+}
+
+
+/*
* Public function for closing arrays and maps. See qcbor/qcbor_encode.h
*/
void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *me, uint8_t uMajorType)
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 17ee051..3ab3557 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Copyright (c) 2021, Arm Limited.
All rights reserved.
@@ -815,4 +815,48 @@
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+const char *UBAdvanceTest(void)
+{
+ #define ADVANCE_TEST_SIZE 10
+ UsefulOutBuf_MakeOnStack(UOB, ADVANCE_TEST_SIZE);
+ UsefulBuf Place = UsefulOutBuf_GetOutPlace(&UOB);
+ if(Place.len != 10) {
+ return "GetOutPlace wrong size";
+ }
+
+ memset(Place.ptr, 'x', Place.len/2);
+
+ UsefulOutBuf_Advance(&UOB, Place.len/2);
+
+ UsefulOutBuf_AppendByte(&UOB, 'y');
+
+ Place = UsefulOutBuf_GetOutPlace(&UOB);
+ if(Place.len != ADVANCE_TEST_SIZE/2 -1 ) {
+ return "GetOutPlace wrong size 2";
+ }
+
+ memset(Place.ptr, 'z', Place.len);
+
+ UsefulOutBuf_Advance(&UOB, Place.len);
+
+ UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
+
+ UsefulBuf_Compare(O, UsefulBuf_FROM_SZ_LITERAL("xxxxxyzzzz"));
+
+ Place = UsefulOutBuf_GetOutPlace(&UOB);
+ if(Place.len != 0 || Place.ptr != NULL) {
+ return "GetOutPlace not null";
+ }
+
+ if(UsefulOutBuf_GetError(&UOB)) {
+ return "GetOutPlace error set";
+ }
+
+ UsefulOutBuf_Advance(&UOB, 1);
+ if(!UsefulOutBuf_GetError(&UOB)) {
+ return "Advance off end didn't set error";
+ }
+
+ return NULL;
+}
diff --git a/test/UsefulBuf_Tests.h b/test/UsefulBuf_Tests.h
index 0d06206..235358e 100644
--- a/test/UsefulBuf_Tests.h
+++ b/test/UsefulBuf_Tests.h
@@ -50,4 +50,6 @@
const char * UBUTest_CopyUtil(void);
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+const char * UBAdvanceTest(void);
+
#endif
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 70fc014..edb0861 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Copyright (c) 2021, Arm Limited.
All rights reserved.
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index d3ada13..fd9f544 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -2875,3 +2875,122 @@
return 0;
}
+
+
+static const uint8_t spExpectedForOpenBytes[] = {
+ 0x50, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+ 0x78
+};
+
+static const uint8_t spExpectedForOpenBytes2[] = {
+ 0xA4, 0x0A, 0x16, 0x14, 0x42, 0x78, 0x78, 0x66,
+ 0x74, 0x68, 0x69, 0x72, 0x74, 0x79, 0x43, 0x79,
+ 0x79, 0x79, 0x18, 0x28, 0x81, 0x40
+};
+
+int32_t
+OpenCloseBytesTest(void)
+{
+ UsefulBuf_MAKE_STACK_UB( TestBuf, 20);
+ UsefulBuf_MAKE_STACK_UB( TestBuf2, 30);
+ QCBOREncodeContext EC;
+ UsefulBuf Place;
+ UsefulBufC Encoded;
+ QCBORError uErr;
+
+ /* Normal use case -- add a byte string that fits */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_OpenBytes(&EC, &Place);
+ if(Place.ptr != TestBuf.ptr ||
+ Place.len != TestBuf.len) {
+ return 1;
+ }
+ Place.len -= 4;
+ UsefulBuf_Set(Place, 'x');
+ QCBOREncode_CloseBytes(&EC, Place.len);
+ QCBOREncode_Finish(&EC, &Encoded);
+ if(UsefulBuf_Compare(Encoded,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedForOpenBytes))) {
+ return 2;
+ }
+
+
+ /* Open a byte string with no room left */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_AddSZString(&EC, "0123456789012345678");
+ QCBOREncode_OpenBytes(&EC, &Place);
+ if(Place.ptr != NULL ||
+ Place.len != 0) {
+ return 3;
+ }
+
+ /* Try to extend byte string past end of encoding output buffer */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_AddSZString(&EC, "012345678901234567");
+ QCBOREncode_OpenBytes(&EC, &Place);
+ /* Don't bother to write any bytes*/
+ QCBOREncode_CloseBytes(&EC, Place.len+1);
+ uErr = QCBOREncode_GetErrorState(&EC);
+ if(uErr != QCBOR_ERR_BUFFER_TOO_SMALL) {
+ return 4;
+ }
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ /* Close a byte string without opening one. */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_AddSZString(&EC, "012345678");
+ QCBOREncode_CloseBytes(&EC, 1);
+ uErr = QCBOREncode_GetErrorState(&EC);
+ if(uErr != QCBOR_ERR_TOO_MANY_CLOSES) {
+ return 5;
+ }
+
+ /* Forget to close a byte string */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_AddSZString(&EC, "012345678");
+ QCBOREncode_OpenBytes(&EC, &Place);
+ uErr = QCBOREncode_Finish(&EC, &Encoded);
+ if(uErr != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
+ return 6;
+ }
+
+ /* Try to open a byte string in a byte string */
+ QCBOREncode_Init(&EC, TestBuf);
+ QCBOREncode_AddSZString(&EC, "012345678");
+ QCBOREncode_OpenBytes(&EC, &Place);
+ QCBOREncode_OpenBytes(&EC, &Place);
+ uErr = QCBOREncode_GetErrorState(&EC);
+ if(uErr != QCBOR_ERR_OPEN_BYTE_STRING) {
+ return 7;
+ }
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+ /* A successful case with a little complexity */
+ QCBOREncode_Init(&EC, TestBuf2);
+ QCBOREncode_OpenMap(&EC);
+ QCBOREncode_AddInt64ToMapN(&EC, 10, 22);
+ QCBOREncode_OpenBytesInMapN(&EC, 20, &Place);
+ Place.len = 2;
+ UsefulBuf_Set(Place, 'x');
+ QCBOREncode_CloseBytes(&EC, 2);
+ QCBOREncode_OpenBytesInMapSZ(&EC, "thirty", &Place);
+ Place.len = 3;
+ UsefulBuf_Set(Place, 'y');
+ QCBOREncode_CloseBytes(&EC, 3);
+ QCBOREncode_OpenArrayInMapN(&EC, 40);
+ QCBOREncode_OpenBytes(&EC, &Place);
+ QCBOREncode_CloseBytes(&EC, 0);
+ QCBOREncode_CloseArray(&EC);
+ QCBOREncode_CloseMap(&EC);
+ uErr = QCBOREncode_Finish(&EC, &Encoded);
+ if(uErr != QCBOR_SUCCESS) {
+ return 8;
+ }
+ if(UsefulBuf_Compare(Encoded,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedForOpenBytes2))) {
+ return 9;
+ }
+
+ return 0;
+}
diff --git a/test/qcbor_encode_tests.h b/test/qcbor_encode_tests.h
index 69f694a..bac1085 100644
--- a/test/qcbor_encode_tests.h
+++ b/test/qcbor_encode_tests.h
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -41,11 +41,6 @@
- All the functions in qcbor_encode.h are called once in the aggregation of all
the tests below.
- - All the types that are supported are given as input and parsed by these tests
-
- - There is some hostile input such as invalid lengths and CBOR too complex
- and types this parser doesn't handle
-
*/
@@ -141,10 +136,11 @@
*/
int32_t AllAddMethodsTest(void);
+
/*
The binary string wrapping of maps and arrays used by COSE
*/
-int32_t BstrWrapTest(void);
+int32_t BstrWrapTest(void);
/*
@@ -190,5 +186,11 @@
int32_t QCBORHeadTest(void);
+/* Fully test QCBOREncode_OpenBytes(), QCBOREncode_CloseBytes()
+ * and friends.
+ */
+int32_t OpenCloseBytesTest(void);
+
+
#endif /* defined(__QCBOR__qcbor_encode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index a5c6635..54cd883 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -60,11 +60,13 @@
TEST_ENTRY(UOBTest_BoundaryConditionsTest),
TEST_ENTRY(UBMacroConversionsTest),
TEST_ENTRY(UBUtilTests),
- TEST_ENTRY(UIBTest_IntegerFormat)
+ TEST_ENTRY(UIBTest_IntegerFormat),
+ TEST_ENTRY(UBAdvanceTest)
};
static test_entry s_tests[] = {
+ TEST_ENTRY(OpenCloseBytesTest),
TEST_ENTRY(EnterBstrTest),
TEST_ENTRY(IntegerConvertTest),
TEST_ENTRY(EnterMapTest),