OpenBytes() is mostly working and somewhat tested
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 748bc56..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.
@@ -309,49 +310,53 @@
void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
{
/* This function is a trimmed down version of
- UsefulOutBuf_InsertUsefulBuf() */
+ * 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;
- }
+ /* 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 */
- }
+ /* 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;
- }
+ /* 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;
- }
+ /* 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;
}
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 760de0e..6cfeb8b 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);
@@ -931,51 +934,30 @@
}
+/*
+ * Public function for opening a byte string. See qcbor/qcbor_encode.h
+ */
void QCBOREncode_OpenBytes(QCBOREncodeContext *pMe, UsefulBuf *pPlace)
{
- /* Add one item to the nesting level we are in for the new map or array */
- IncrementMapOrArrayCount(pMe);
-
- /* The offset where the length of an array or map will get written
- * is stored in a uint32_t, not a size_t to keep stack usage
- * smaller. This checks to be sure there is no wrap around when
- * recording the offset. Note that on 64-bit machines CBOR larger
- * than 4GB can be encoded as long as no array/map offsets occur
- * past the 4GB mark, but the public interface says that the
- * maximum is 4GB to keep the discussion simpler.
- */
- size_t uEndPosition = UsefulOutBuf_GetEndPosition(&(pMe->OutBuf));
-
- /* QCBOR_MAX_ARRAY_OFFSET is slightly less than UINT32_MAX so this
- * code can run on a 32-bit machine and tests can pass on a 32-bit
- * machine. If it was exactly UINT32_MAX, then this code would not
- * compile or run on a 32-bit machine and an #ifdef or some machine
- * size detection would be needed reducing portability.
- */
- if(uEndPosition >= QCBOR_MAX_ARRAY_OFFSET) {
- pMe->uError = QCBOR_ERR_BUFFER_TOO_LARGE;
-
- *pPlace = NULLUsefulBuf;
-
- } else {
- /* Increase nesting level because this is a map or array. Cast
- * from size_t to uin32_t is safe because of check above.
- */
- // TODO: proper type constant
- pMe->uError = Nesting_Increase(&(pMe->nesting), 200, (uint32_t)uEndPosition);
-
- *pPlace = UsefulOutBuf_Stuff(&(pMe->OutBuf));
+ *pPlace = UsefulOutBuf_GetOutPlace(&(pMe->OutBuf));
+ if(!UsefulBuf_IsNULL(*pPlace)){
+ 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, size_t uAmount)
{
- UsefulOutBuf_StuffDone(&(pMe->OutBuf), uAmount);
- // TODO: sort out the major type
- InsertCBORHead(pMe,
- CBOR_MAJOR_TYPE_BYTE_STRING,
- uAmount);
+ UsefulOutBuf_Advance(&(pMe->OutBuf), uAmount);
+ if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
+ pMe->uError = QCBOR_ERR_ADVANCE_TOO_FAR;
+ return;
+ }
+
+ InsertCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR, uAmount);
}