Merge master (what will be 1.4.2) into dev
diff --git a/LICENSE b/LICENSE
index bf7753f..6dc0157 100644
--- a/LICENSE
+++ b/LICENSE
@@ -33,4 +33,5 @@
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 9adfefe..fa511d2 100644
--- a/README.md
+++ b/README.md
@@ -183,7 +183,7 @@
## Code Status
-The official current release is version 1.3. Changes over the last few
+The official current release is version 1.4.1 Changes over the last few
years have been only minor bug fixes, minor feature additions and
documentation improvements. QCBOR 1.x is highly stable.
@@ -553,44 +553,8 @@
* Máté Tóth-Pál for float-point disabling and other
* Dave Thaler for portability to Windows
-## Copyright and License
-
-QCBOR is available under what is essentially the 3-Clause BSD License.
-
-Files created inside Qualcomm and open-sourced through CAF (The Code
-Aurora Forum) have a slightly modified 3-Clause BSD License. The
-modification additionally disclaims NON-INFRINGEMENT.
-
-Files created after release to CAF use the standard 3-Clause BSD
-License with no modification. These files have the SPDX license
-identifier, "SPDX-License-Identifier: BSD-3-Clause" in them.
-
-### BSD-3-Clause license
-
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holder nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
### Copyright for this README
-Copyright (c) 2018-2021, Laurence Lundblade. All rights reserved.
+Copyright (c) 2018-2024, Laurence Lundblade. All rights reserved.
Copyright (c) 2021-2023, Arm Limited. All rights reserved.
diff --git a/cmd_line_main.c b/cmd_line_main.c
index 4df6e98..da5d071 100644
--- a/cmd_line_main.c
+++ b/cmd_line_main.c
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 9/13/18
=============================================================================*/
diff --git a/example.c b/example.c
index d580c78..ed5d597 100644
--- a/example.c
+++ b/example.c
@@ -6,7 +6,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 6/30/2020
========================================================================== */
diff --git a/example.h b/example.h
index b5bcf4b..903b3f5 100644
--- a/example.h
+++ b/example.h
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 6/30/20
=============================================================================*/
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index d67dd85..819a0d5 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -43,9 +43,12 @@
when who what, where, why
-------- ---- --------------------------------------------------
- 1/7/2024 llundblade Add UsefulInputBuf_Compare().
+ 08/14/2024 llundblade Add UsefulOutBuf_RetrieveOutputStorage().
+ 08/13/2024 llundblade Add UsefulInputBuf_RetrieveUndecodedInput().
+ 08/08/2024 llundblade Add UsefulOutBuf_SubString().
10/05/2024 llundblade Add Xxx_OffsetToPointer.
28/02/2024 llundblade Rearrange UsefulOutBuf_Compare().
+ 1/7/2024 llundblade Add UsefulInputBuf_Compare().
19/11/2023 llundblade Add UsefulOutBuf_GetOutput().
19/11/2023 llundblade Add UsefulOutBuf_Swap().
19/11/2023 llundblade Add UsefulOutBuf_Compare().
@@ -1410,6 +1413,36 @@
UsefulOutBuf_OutUBufOffset(UsefulOutBuf *pUOutBuf, size_t uOffset);
+/*
+ * @brief Return a substring of the output data.
+ *
+ * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
+ * @param[in] uStart Offset of start of substring.
+ * @param[in] uLen Length of substring.
+ *
+ * This is the same as UsefulOutBuf_OutUBuf(), but returns a
+ * substring. @c NULLUsefulBufC is returned if the requested substring
+ * is off the end of the output bytes or if in error state.
+ */
+UsefulBufC UsefulOutBuf_SubString(UsefulOutBuf *pUOutBuf,
+ const size_t uStart,
+ const size_t uLen);
+
+
+/**
+ * @brief Retrieve the storage buffer passed in to UsefulOutBuf_Init().
+ *
+ * @param[in] pUOutBuf The encoding context.
+ *
+ * @return The output storage buffer passed to UsefulOutBuf_Init().
+ *
+ * This doesn't give any information about how much has been encoded
+ * or the error state. It just returns the exact @ref UsefulOutBuf given
+ * to UsefulOutBuf_Init().
+ */
+static UsefulBuf UsefulOutBuf_RetrieveOutputStorage(UsefulOutBuf *pUOutBuf);
+
+
/**
* @brief Compare bytes at offsets.
*
@@ -1823,6 +1856,17 @@
static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
+/** @brief Retrieve the undecoded input buffer.
+ *
+ * @param[in] pUInBuf Pointer to the @ref UsefulInputBuf.
+ *
+ * @return The input that was given to UsefulInputBuf_Init().
+ *
+ * A simple convenience method, should it be useful to get the original input back.
+ */
+static UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pUInBuf);
+
+
/**
* @brief Compare two ranges of bytes somewhere in the input buffer.
*
@@ -1851,6 +1895,8 @@
const size_t uLen2);
+
+
/*----------------------------------------------------------
Inline implementations.
*/
@@ -2353,6 +2399,12 @@
}
+static inline UsefulBuf UsefulOutBuf_RetrieveOutputStorage(UsefulOutBuf *pMe)
+{
+ return pMe->UB;
+}
+
+
static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
@@ -2621,6 +2673,11 @@
pMe->UB.len = uNewLen;
}
+static inline UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pMe)
+{
+ return pMe->UB;
+}
+
#ifdef __cplusplus
}
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index e51ebc6..74e20ee 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -63,6 +63,7 @@
#define QCBOR_VERSION_PATCH 0
+
/**
* This define indicates a version of QCBOR that supports spiffy
* decode, the decode functions found in qcbor_spiffy_decode.h.
@@ -118,36 +119,36 @@
* are types defined in RFC 8949 and some additional ones
* in the IANA CBOR tags registry.
*/
-/** See QCBOREncode_AddDateString(). */
+/** See QCBOREncode_AddTDateString(). */
#define CBOR_TAG_DATE_STRING 0
-/** See QCBOREncode_AddDateEpoch(). */
+/** See QCBOREncode_AddTDateEpoch(). */
#define CBOR_TAG_DATE_EPOCH 1
-/** See QCBOREncode_AddPositiveBignum(). */
+/** See QCBOREncode_AddTPositiveBignum(). */
#define CBOR_TAG_POS_BIGNUM 2
-/** See QCBOREncode_AddNegativeBignum(). */
+/** See QCBOREncode_AddTNegativeBignum(). */
#define CBOR_TAG_NEG_BIGNUM 3
/** CBOR tag for a two-element array representing a fraction with a
* mantissa and base-10 scaling factor. See
- * QCBOREncode_AddDecimalFraction() and @ref expAndMantissa. */
+ * QCBOREncode_AddTDecimalFraction() and @ref expAndMantissa. */
#define CBOR_TAG_DECIMAL_FRACTION 4
/** CBOR tag for a two-element array representing a fraction with a
- * mantissa and base-2 scaling factor. See QCBOREncode_AddBigFloat()
+ * mantissa and base-2 scaling factor. See QCBOREncode_AddTBigFloat()
* and @ref expAndMantissa. */
#define CBOR_TAG_BIGFLOAT 5
/** Not Decoded by QCBOR. Tag for COSE format encryption with no
- * recipient identification. See [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152). No API is provided for this
- * tag. */
+ * recipient identification. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided
+ * for this tag. */
#define CBOR_TAG_COSE_ENCRYPT0 16
#define CBOR_TAG_COSE_ENCRYPTO 16
/** Not Decoded by QCBOR. Tag for COSE format MAC'd data with no
- * recipient identification. See [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ * recipient identification. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
* tag. */
#define CBOR_TAG_COSE_MAC0 17
/** Tag for COSE format single signature signing. No API is provided
- * for this tag. See [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152). */
+ * for this tag. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). */
#define CBOR_TAG_COSE_SIGN1 18
/** A hint that the following byte string should be encoded in
* Base64URL when converting to JSON or similar text-based
@@ -162,12 +163,12 @@
* QCBOREncode_AddBytes(). */
#define CBOR_TAG_ENC_AS_B64 22
/** A hint that the following byte string should be encoded in base-16
- * format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
- * converting to JSON or similar text-based
- * representations. Essentially, Base-16 encoding is the standard
- * case- insensitive hex encoding and may be referred to as
- * "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
- * the call to QCBOREncode_AddBytes(). */
+ * format per [RFC 4648]
+ * (https://www.rfc-editor.org/rfc/rfc4648.html) when converting to
+ * JSON or similar text-based representations. Essentially, Base-16
+ * encoding is the standard case- insensitive hex encoding and may be
+ * referred to as "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16)
+ * before the call to QCBOREncode_AddBytes(). */
#define CBOR_TAG_ENC_AS_B16 23
/** See QCBORDecode_EnterBstrWrapped()). */
#define CBOR_TAG_CBOR 24
@@ -184,40 +185,40 @@
/** See QCBOREncode_AddBinaryUUID(). */
#define CBOR_TAG_BIN_UUID 37
/** The data is a CBOR Web Token per [RFC 8392]
- * (https://tools.ietf.org/html/rfc8932). No API is provided for this
+ * (https://www.rfc-editor.org/rfc/rfc8392.html). No API is provided for this
* tag. */
#define CBOR_TAG_CWT 61
-/** Tag for COSE format encryption. See [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Tag for COSE format encryption. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
* tag. */
#define CBOR_TAG_CBOR_SEQUENCE 63
-/** Not Decoded by QCBOR. Tag for COSE format encrypt. See [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format encrypt. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
* tag. */
#define CBOR_TAG_COSE_ENCRYPT 96
#define CBOR_TAG_ENCRYPT 96
-/** Not Decoded by QCBOR. Tag for COSE format MAC. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format MAC. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
tag. */
#define CBOR_TAG_COSE_MAC 97
#define CBOR_TAG_MAC 97
-/** Not Decoded by QCBOR. Tag for COSE format signed data. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format signed data. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
tag. */
#define CBOR_TAG_COSE_SIGN 98
#define CBOR_TAG_SIGN 98
/** Tag for date counted by days from Jan 1 1970 per [RFC 8943]
- * (https://tools.ietf.org/html/rfc8943). See
+ * (https://www.rfc-editor.org/rfc/rfc8943.html). See
* QCBOREncode_AddTDaysEpoch(). */
#define CBOR_TAG_DAYS_EPOCH 100
/** Not Decoded by QCBOR. World geographic coordinates. See ISO 6709, [RFC 5870]
- * (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
+ * (https://www.rfc-editor.org/rfc/rfc5870.html) and WGS-84. No API is
* provided for this tag. */
#define CBOR_TAG_GEO_COORD 103
/** Binary MIME.*/
#define CBOR_TAG_BINARY_MIME 257
/** Tag for date string without time or time zone per [RFC 8943]
- * (https://tools.ietf.org/html/rfc8943). See
+ * (https://www.rfc-editor.org/rfc/rfc8943.html). See
* QCBOREncode_AddTDaysString(). */
#define CBOR_TAG_DAYS_STRING 1004
/** The magic number, self-described CBOR. No API is provided for this
@@ -278,8 +279,9 @@
* different type than is currently open. */
QCBOR_ERR_CLOSE_MISMATCH = 5,
- /** During encoding, the array or map had too many items in it.
- * This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
+ /** During encoding, the array or map had too many items in it. The
+ * limits are @ref QCBOR_MAX_ITEMS_IN_ARRAY and
+ * @ref QCBOR_MAX_ITEMS_IN_MAP. */
QCBOR_ERR_ARRAY_TOO_LONG = 6,
/** During encoding, more arrays or maps were closed than
@@ -366,9 +368,9 @@
QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP = 41,
/** During decoding, the array or map had too many items in it.
- * This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,534,
- * UINT16_MAX - 1. This error makes no further decoding
- * possible. */
+ * This limit is @ref QCBOR_MAX_ITEMS_IN_ARRAY (65,534) for
+ * arrays and @ref QCBOR_MAX_ITEMS_IN_MAP (32,767) for maps. This
+ * error makes no further decoding possible. */
QCBOR_ERR_ARRAY_DECODE_TOO_LONG = 42,
/** When decoding, a string's size is greater than what a size_t
@@ -598,14 +600,19 @@
/**
- * The maximum number of items in a single array or map when encoding or
- * decoding.
+ * The maximum number of items in a single array when encoding or
+ * decoding. See also @ref QCBOR_MAX_ITEMS_IN_MAP.
*/
#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1) /* -1 is because the
* value UINT16_MAX is
* used to indicate
* indefinite-length.
*/
+/**
+ * The maximum number of items in a single map when encoding or
+ * decoding. See also @ref QCBOR_MAX_ITEMS_IN_ARRAY.
+ */
+#define QCBOR_MAX_ITEMS_IN_MAP (QCBOR_MAX_ITEMS_IN_ARRAY/2)
#ifdef __cplusplus
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index f2f4a4b..8b56b5d 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -1282,6 +1282,19 @@
/**
+ * @brief Retrieve the undecoded input buffer.
+ *
+ * @param[in] pCtx The decode context.
+ *
+ * @return The input that was given to QCBORDecode_Init().
+ *
+ * A simple convenience method, should it be useful to get the original input back.
+ */
+static UsefulBufC
+QCBORDecode_RetrieveUndecodedInput(QCBORDecodeContext *pCtx);
+
+
+/**
* @brief Get the decoding error.
*
* @param[in] pCtx The decoder context.
@@ -1713,6 +1726,12 @@
return (uint32_t)UsefulInputBuf_Tell(&(pMe->InBuf));
}
+static inline UsefulBufC
+QCBORDecode_RetrieveUndecodedInput(QCBORDecodeContext *pMe)
+{
+ return UsefulInputBuf_RetrieveUndecodedInput(&(pMe->InBuf));
+}
+
static inline QCBORError
QCBORDecode_GetError(QCBORDecodeContext *pMe)
{
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 96a91e1..a1a1aae 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -57,10 +57,11 @@
* # QCBOR Overview
*
* This implements CBOR -- Concise Binary Object Representation as
- * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
- * information is at http://cbor.io. This is a near-complete implementation of
- * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
- * Sequences is also supported. Limitations are listed further down.
+ * defined in [RFC 8949] (https://www.rfc-editor.org/rfc/rfc8949.html).
+ * More information is at http://cbor.io. This is a near-complete
+ * implementation of the specification. [RFC 8742]
+ * (https://www.rfc-editor.org/rfc/rfc8742.html) CBOR Sequences is
+ * also supported. Limitations are listed further down.
*
* See @ref Encoding for general discussion on encoding,
* @ref BasicDecode for general discussion on the basic decode features
@@ -222,12 +223,13 @@
* Note that when you nest arrays or maps in a map, the nested array or
* map has a label.
*
- * Many CBOR-based protocols start with an array or map. This makes them
- * self-delimiting. No external length or end marker is needed to know
- * the end. It is also possible not start this way, in which case this
- * it is usually called a CBOR sequence which is described in
- * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
- * either just by whether the first item added is an array, map or other.
+ * Many CBOR-based protocols start with an array or map. This makes
+ * them self-delimiting. No external length or end marker is needed to
+ * know the end. It is also possible not start this way, in which case
+ * this it is usually called a CBOR sequence which is described in
+ * [RFC 8742] (https://www.rfc-editor.org/rfc/rfc8742.html). This
+ * encoder supports either just by whether the first item added is an
+ * array, map or other.
*
* If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
* the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
@@ -413,7 +415,7 @@
/**
- * Initialize the encoder to prepare to encode some CBOR.
+ * Initialize the encoder.
*
* @param[in,out] pCtx The encoder context to initialize.
* @param[in] Storage The buffer into which the encoded result
@@ -656,21 +658,20 @@
* protocols. If integers can be kept between -23 and 23
* they will be encoded in one byte including the major type.
*
- * If you pass a smaller int, say an @c int16_t or a small value, say
- * 100, the encoding will still be CBOR's most compact that can
+ * If you pass a smaller integer, like @c int16_t or a small value,
+ * like 100, the encoding will still be CBOR's most compact that can
* represent the value. For example, CBOR always encodes the value 0
* as one byte, 0x00. The representation as 0x00 includes
* identification of the type as an integer too as the major type for
- * an integer is 0. See [RFC 8949]
- * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
- * of CBOR encoding. This compact encoding is also preferred
- * serialization CBOR as per section 34.1 in RFC 8949.
+ * an integer is 0. See [RFC 8949 Appendix A]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-appendix.a)
+ * for more examples of CBOR encoding. This compact encoding is
+ * preferred serialization CBOR as per [RFC 8949 section 4.1]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-4.1)
*
* There are no functions to add @c int16_t or @c int32_t because they
* are not necessary because this always encodes to the smallest
- * number of bytes based on the value (If this code is running on a
- * 32-bit machine having a way to add 32-bit integers would reduce
- * code size some).
+ * number of bytes based on the value.
*
* If the encoding context is in an error state, this will do
* nothing. If an error occurs when adding this integer, the internal
@@ -683,10 +684,10 @@
QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
static void
-QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
+QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nNum);
static void
-QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
+QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t nNum);
/**
@@ -765,9 +766,9 @@
* @param[in] pCtx The encoding context to add the text to.
* @param[in] Text Pointer and length of text to add.
*
- * The text passed in must be unencoded UTF-8 according to [RFC 3629]
- * (https://tools.ietf.org/html/rfc3629). There is no NULL
- * termination. The text is added as CBOR major type 3.
+ * The text passed in must be unencoded UTF-8 according to
+ * [RFC 3629] (https://www.rfc-editor.org/rfc/rfc3629.html). There is
+ * no NULL termination. The text is added as CBOR major type 3.
*
* If called with @c nBytesLen equal to 0, an empty string will be
* added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
@@ -832,6 +833,7 @@
* @param[in] pCtx The encoding context to add the double to.
* @param[in] dNum The double-precision number to add.
*
+<<<<<<< HEAD
* This encodes using preferred serialization, selectively encoding
* the input floating-point number as either double-precision,
* single-precision or half-precision. Infinity, NaN and 0 are always
@@ -855,6 +857,32 @@
* can't be directly decoded into an int64_t or uint64_t. See
* QCBORDecode_GetNumberConvertPrecisely(), a good method to use to
* decode dCBOR.
+=======
+ * This encodes and outputs a double-precision floating-point
+ * number. CBOR major type 7 is used.
+ *
+ * This implements preferred serialization, selectively encoding the
+ * double-precision floating-point number as either double-precision,
+ * single-precision or half-precision. Infinity, NaN and zero are
+ * always encoded as half-precision. If no precision will be lost in
+ * the conversion to half-precision, then it will be converted and
+ * encoded. If not and no precision will be lost in conversion to
+ * single-precision, then it will be converted and encoded. If not,
+ * then no conversion is performed, and it encoded as a
+ * double-precision.
+ *
+ * Half-precision floating-point numbers take up two bytes, half that
+ * of single-precision, one quarter of double-precision. Preferred
+ * serialization can therefore reduce message size down to one quarter
+ * of the original if most of the values are zero, infinity or NaN.
+ *
+ * When decoded, QCBOR returns these values as double-precision even
+ * if they were encoded as single or half-precision.
+ *
+ * It is possible to disable preferred serialization when compiling
+ * QCBOR. In that case, this operates the same as
+ * QCBOREncode_AddDoubleNoPreferred().
+>>>>>>> master
*
* Error handling is the same as QCBOREncode_AddInt64().
*
@@ -884,11 +912,16 @@
/**
* @brief Add a single-precision floating-point number to the encoded output.
*
- * @param[in] pCtx The encoding context to add the double to.
+ * @param[in] pCtx The encoding context to add the single to.
* @param[in] fNum The single-precision number to add.
*
* This is identical to QCBOREncode_AddDouble() except the input is
+<<<<<<< HEAD
* single-precision. It also supports dCBOR.
+=======
+ * single-precision. The preferred serialization output will be either
+ * single-precision or half-precision.
+>>>>>>> master
*
* See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
* and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
@@ -949,7 +982,7 @@
static void
QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
-#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
/**
@@ -1056,7 +1089,7 @@
* @param[in] nDays Number of days before or after 1970-01-0.
*
* This date format is described in
- * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
+ * [RFC 8943] (https://www.rfc-editor.org/rfc/rfc8943.html).
*
* The preferred integer serialization rules apply here so the date
* will be encoded in a minimal number of bytes. Until about the year
@@ -1180,7 +1213,8 @@
* @param[in] Bytes Pointer and length of the binary UUID.
*
* A binary UUID as defined in [RFC 4122]
- * (https://tools.ietf.org/html/rfc4122) is added to the output.
+ * (https://www.rfc-editor.org/rfc/rfc4122.html) is added to the
+ * output.
*
* It is output as CBOR major type 2, a binary string, with tag @ref
* CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
@@ -1216,10 +1250,10 @@
/**
* @brief Add a positive big number using preferred serialization.
*
- * @param[in] pCtx The encoding context to add the big number to.
+ * @param[in] pCtx The encoding context.
* @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
* @ref QCBOR_ENCODE_AS_BORROWED.
- * @param[in] BigNumber Pointer and length of the big number.
+ * @param[in] BigNumber Pointer and length of the big number.
*
* @c BigNumber makes up an aribtrary precision integer in
* network/big-endian byte order. The first byte is the most
@@ -1228,7 +1262,8 @@
* If the value in @c BigNumber is greater than @c UINT64_MAX, this
* will be encoded as the CBOR tag @ref CBOR_TAG_POS_BIGNUM. If less
* then, it will be output as a type 0 integer. This is as required
- * for preferred serialization described in RFC 8949 section 3.4.3.
+ * for preferred serialization described in [RFC 8949 section 3.4.3]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.3).
*
* See also QCBOREncode_AddTPositiveBignumNoPreferred().
*
@@ -1291,7 +1326,7 @@
/**
* @brief Add a positive big number without preferred serialization.
*
- * @param[in] pCtx The encoding context to add the big number to.
+ * @param[in] pCtx The encoding context.
* @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
* @ref QCBOR_ENCODE_AS_BORROWED.
* @param[in] BigNumber Pointer and length of the big number.
@@ -1325,7 +1360,7 @@
* @param[in] pCtx The encoding context to add the big number to.
* @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
* @ref QCBOR_ENCODE_AS_BORROWED.
- * @param[in] BigNum Pointer and length of the big number.
+ * @param[in] BigNumber Pointer and length of the big number.
*
* This outputs @c BigNum as a type 1 if the value is greater than or
* equal to -(2^64), and as tag 3 if less than. This is as required
@@ -1348,19 +1383,19 @@
void
QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
uint8_t uTagRequirement,
- UsefulBufC BigNum);
+ UsefulBufC BigNumber);
static void
QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
const char *szLabel,
uint8_t uTagRequirement,
- UsefulBufC Bytes);
+ UsefulBufC BigNumber);
static void
QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
int64_t nLabel,
uint8_t uTagRequirement,
- UsefulBufC Bytes);
+ UsefulBufC BigNumber);
/**
@@ -1427,6 +1462,7 @@
UsefulBufC BigNumber);
+
#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
/**
* @brief Add a decimal fraction to the encoded output.
@@ -1702,7 +1738,7 @@
UsefulBufC Mantissa,
bool bIsNegative,
int64_t nBase2Exponent);
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
/**
@@ -1714,7 +1750,7 @@
* @param[in] URI Pointer and length of the URI.
*
* The format of URI must be per [RFC 3986]
- * (https://tools.ietf.org/html/rfc3986).
+ * (https://www.rfc-editor.org/rfc/rfc3986.html).
*
* It is output as CBOR major type 3, a text string, with tag @ref
* CBOR_TAG_URI indicating the text string is a URI.
@@ -1766,7 +1802,7 @@
* @param[in] B64Text Pointer and length of the base-64 encoded text.
*
* The text content is Base64 encoded data per [RFC 4648]
- * (https://tools.ietf.org/html/rfc4648).
+ * (https://www.rfc-editor.org/rfc/rfc4648.html).
*
* It is output as CBOR major type 3, a text string, with tag @ref
* CBOR_TAG_B64 indicating the text string is Base64 encoded.
@@ -1774,7 +1810,7 @@
static void
QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
uint8_t uTagRequirement,
- UsefulBufC B64Text);
+ UsefulBufC B64Text);
static void
QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
@@ -1813,8 +1849,8 @@
* @ref QCBOR_ENCODE_AS_BORROWED.
* @param[in] B64Text Pointer and length of the base64url encoded text.
*
- * The text content is base64URL encoded text as per [RFC 4648]
- * (https://tools.ietf.org/html/rfc4648).
+ * The text content is base64URL encoded text as per
+ * [RFC 4648] (https://www.rfc-editor.org/rfc/rfc4648.html).
*
* It is output as CBOR major type 3, a text string, with tag
* @ref CBOR_TAG_B64URL indicating the text string is a Base64url
@@ -1909,7 +1945,7 @@
* @param[in] MIMEData Pointer and length of the MIME data.
*
* The text content is in MIME format per [RFC 2045]
- * (https://tools.ietf.org/html/rfc2045) including the headers.
+ * (https://www.rfc-editor.org/rfc/rfc2045.html) including the headers.
*
* It is output as CBOR major type 2, a binary string, with tag
* @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
@@ -1969,11 +2005,11 @@
* @ref QCBOR_ENCODE_AS_BORROWED.
* @param[in] szDate Null-terminated string with date to add.
*
- * The string szDate should be in the form of [RFC 3339]
- * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
- * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
- * described in section 3.4.1 in [RFC 8949]
- * (https://tools.ietf.org/html/rfc8949).
+ * The string szDate should be in the form of
+ * [RFC 3339] (https://www.rfc-editor.org/rfc/rfc3339.html) as defined
+ * by section 3.3 in [RFC 4287] (https://www.rfc-editor.org/rfc/rfc4287.html).
+ * This is as described in section 3.4.1 in [RFC 8949]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section3.1.4).
*
* Note that this function doesn't validate the format of the date
* string at all. If you add an incorrect format date string, the
@@ -2026,10 +2062,10 @@
* @param[in] szDate Null-terminated string with date to add.
*
* This date format is described in
- * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
+ * [RFC 8943] (https://www.rfc-editor.org/rfc/rfc8943.html), but that mainly
* references RFC 3339. The string szDate must be in the forrm
* specified the ABNF for a full-date in
- * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
+ * [RFC 3339] (https://www.rfc-editor.org/rfc/rfc3339.html). Examples of this
* are "1985-04-12" and "1937-01-01". The time and the time zone are
* never included.
*
@@ -2111,7 +2147,7 @@
*
* Note that this value will not translate to JSON.
*
- * This Undef doesn't have any special meaning in CBOR such as a
+ * "undef" doesn't have any special meaning in CBOR such as a
* terminating value for a string or an empty value.
*
* Error handling is the same as QCBOREncode_AddInt64().
@@ -2256,8 +2292,8 @@
* text strings, then just call the QCBOREncode_AddXxx() function
* explicitly to add the label. Then call it again to add the value.
*
- * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
- * more information on creating maps.
+ * See the [RFC 8949] (https://www.rfc-editor.org/rfc/rfc8949.html)
+ * for a lot more information on creating maps.
*/
static void
QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
@@ -2399,11 +2435,11 @@
* contain encoded CBOR. This increases nesting level by one.
*
* The typical use case is for encoded CBOR that is to be
- * cryptographically hashed, as part of a [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
- * byte string is taken as input by the hash function (which is why it
- * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
- * recover on decoding with standard CBOR decoders.
+ * cryptographically hashed, as part of a [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html) implementation. The
+ * wrapping byte string is taken as input by the hash function (which
+ * is why it is returned by QCBOREncode_CloseBstrWrap2()). It is also
+ * easy to recover on decoding with standard CBOR decoders.
*
* Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
* avoids having to encode the items first in one buffer (e.g., the
@@ -2442,8 +2478,8 @@
*
* A pointer and length of the enclosed encoded CBOR is returned in @c
* *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
- * this data can be hashed (e.g., with SHA-256) as part of a [RFC
- * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
+ * this data can be hashed (e.g., with SHA-256) as part of a
+ * [RFC 9052, COSE] (https://www.rfc-editor.org/rfc/rfc9052.html)
* implementation. **WARNING**, this pointer and length should be used
* right away before any other calls to @c QCBOREncode_CloseXxx() as
* they will move data around and the pointer and length will no
@@ -2476,7 +2512,7 @@
*
* @param[in] pCtx The encoding context.
*
- * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
+ * This cancels QCBOREncode_BstrWrap() making the encoding as if it
* were never called.
*
* WARNING: This does not work on QCBOREncode_BstrWrapInMap()
@@ -2498,8 +2534,7 @@
* @param[in] Encoded The already-encoded CBOR to add to the context.
*
* The encoded CBOR being added must be fully conforming CBOR. It must
- * be complete with no arrays or maps that are incomplete. While this
- * encoder doesn't ever produce indefinite lengths, it is OK for the
+ * be complete with no arrays or maps that are incomplete. it is OK for the
* raw CBOR added here to have indefinite lengths.
*
* The raw CBOR added here is not checked in anyway. If it is not
@@ -2583,7 +2618,8 @@
*
* This may be called multiple times. It will always return the
* same. It can also be interleaved with calls to
- * QCBOREncode_FinishGetSize().
+ * QCBOREncode_FinishGetSize(). See QCBOREncode_SubString() for a
+ * means to get the thus-far-encoded CBOR.
*
* QCBOREncode_GetErrorState() can be called to get the current
* error state in order to abort encoding early as an optimization, but
@@ -2610,22 +2646,35 @@
/**
- * @brief Indicate whether output buffer is NULL or not.
+ * @brief Indicate whether the output storage buffer is NULL.
*
* @param[in] pCtx The encoding context.
*
* @return 1 if the output buffer is @c NULL.
*
- * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
- * that the size of the generated CBOR can be calculated without
- * allocating a buffer for it. This returns 1 when the output buffer
- * is @c NULL and 0 when it is not.
+ * As described in QCBOREncode_Init(), @c Storage.ptr may be give as @c NULL
+ * for output size calculation. This returns 1 when that is the true, and 0 if not.
*/
static int
QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
/**
+ * @brief Retrieve the storage buffer passed in to QCBOREncode_Init().
+ *
+ * @param[in] pCtx The encoding context.
+ *
+ * @return The output storage buffer passed to QCBOREncode_Init().
+ *
+ * This doesn't give any information about how much has been encoded
+ * or the error state. It just returns the exact @ref UsefulOutBuf given
+ * to QCBOREncode_Init().
+ */
+static UsefulBuf
+QCBOREncode_RetrieveOutputStorage(QCBOREncodeContext *pCtx);
+
+
+/**
* @brief Get the encoding error state.
*
* @param[in] pCtx The encoding context.
@@ -2643,7 +2692,73 @@
/**
- * Encode the "head" of a CBOR data item.
+ * @brief Returns current end of encoded data.
+ *
+ * @param[in] pCtx The encoding context.
+ *
+ * @return Byte offset of end of encoded data.
+ *
+ * The purpose of this is to enable cryptographic hashing over a
+ * subpart of thus far CBOR-encoded data. Then perhaps a signature
+ * over the hashed CBOR is added to the encoded output. There is
+ * nothing specific to hashing or signing in this, so this can be used
+ * for other too.
+ *
+ * Call this to get the offset of the start of the encoded
+ * to-be-hashed CBOR items, then call QCBOREncode_SubString().
+ * QCBOREncode_Tell() can also be called twice, first to get the
+ * offset of the start and second for the offset of the end. Those
+ * offsets can be applied to the output storage buffer.
+ *
+ * This will return successfully even if the encoder is in the error
+ * state.
+ *
+ * WARNING: All definite-length arrays and maps opened before the
+ * first call to QCBOREncode_Tell() must not be closed until the
+ * substring is obtained and processed. Similarly, every
+ * definite-length array or map opened after the first call to
+ * QCBOREncode_Tell() must be closed before the substring is obtained
+ * and processed. The same applies for opened byte strings. There is
+ * no detection of these errors. This occurs because QCBOR goes back
+ * and inserts the lengths of definite-length arrays and maps when
+ * they are closed. This insertion will make the offsets incorrect.
+ */
+static size_t
+QCBOREncode_Tell(QCBOREncodeContext *pCtx);
+
+
+/**
+ * @brief Get a substring of encoded CBOR for cryptographic hash
+ *
+ * @param[in] pCtx The encoding context.
+ * @param[in] uStart The start offset of substring.
+ *
+ * @return Pointer and length of of substring.
+ *
+ * @c uStart is obtained by calling QCBOREncode_Tell() before encoding
+ * the first item in the substring. Then encode some data items. Then
+ * call this. The substring returned contains the encoded data items.
+ *
+ * The substring may have deeply nested arrays and maps as long as any
+ * opened after the call to QCBOREncode_Tell() are closed before this
+ * is called.
+ *
+ * This will return @c NULLUsefulBufC if the encoder is in the error
+ * state or if @c uStart is beyond the end of the thus-far encoded
+ * data items.
+ *
+ * If @c uStart is 0, all the thus-far-encoded CBOR will be returned.
+ * Unlike QCBOREncode_Finish(), this will succeed even if some arrays
+ * and maps are not closed.
+ *
+ * See important usage WARNING in QCBOREncode_Tell()
+ */
+UsefulBufC
+QCBOREncode_SubString(QCBOREncodeContext *pCtx, const size_t uStart);
+
+
+/**
+ * @brief Encode the head of a CBOR data item.
*
* @param Buffer Buffer to output the encoded head to; must be
* @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
@@ -2671,7 +2786,7 @@
* doesn't have to be encoded in a contiguous buffer.
*
* For example, if you have a 100,000 byte binary blob in a buffer that
- * needs to be a bstr encoded and then hashed. You could allocate a
+ * needs to be bstr encoded and then hashed. You could allocate a
* 100,010 byte buffer and encode it normally. Alternatively, you can
* encode the head in a 10 byte buffer with this function, hash that and
* then hash the 100,000 bytes using the same hash context.
@@ -2832,19 +2947,19 @@
static inline void
QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
const char *szLabel,
- const int64_t uNum)
+ const int64_t nNum)
{
QCBOREncode_AddSZString(pMe, szLabel);
- QCBOREncode_AddInt64(pMe, uNum);
+ QCBOREncode_AddInt64(pMe, nNum);
}
static inline void
QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
const int64_t nLabel,
- const int64_t uNum)
+ const int64_t nNum)
{
QCBOREncode_AddInt64(pMe, nLabel);
- QCBOREncode_AddInt64(pMe, uNum);
+ QCBOREncode_AddInt64(pMe, nNum);
}
@@ -2945,10 +3060,6 @@
}
-
-/*
- * Public functions for adding a tag. See qcbor/qcbor_encode.h
- */
static inline void
QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
{
@@ -2957,6 +3068,7 @@
+
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
static inline void
@@ -2983,7 +3095,7 @@
QCBOREncode_Private_AddPreferredDouble(pMe, dNum);
#else /* QCBOR_DISABLE_PREFERRED_FLOAT */
QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
-#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
}
static inline void
@@ -3012,7 +3124,7 @@
QCBOREncode_Private_AddPreferredFloat(pMe, fNum);
#else /* QCBOR_DISABLE_PREFERRED_FLOAT */
QCBOREncode_AddFloatNoPreferred(pMe, fNum);
-#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
}
static inline void
@@ -3068,7 +3180,7 @@
QCBOREncode_AddInt64(pMe, nLabel);
QCBOREncode_AddFloatNoPreferred(pMe, dNum);
}
-#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
@@ -3207,6 +3319,7 @@
}
+
static inline void
QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
const uint8_t uTagRequirement,
@@ -3731,7 +3844,7 @@
bIsNegative,
nBase2Exponent);
}
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
static inline void
@@ -4112,7 +4225,7 @@
pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
return;
}
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
QCBOREncode_Private_AddType7(pMe, 0, uNum);
}
@@ -4368,6 +4481,14 @@
return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
}
+
+static inline UsefulBuf
+QCBOREncode_RetrieveOutputStorage(QCBOREncodeContext *pMe)
+{
+ return UsefulOutBuf_RetrieveOutputStorage(&(pMe->OutBuf));
+}
+
+
static inline QCBORError
QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
{
@@ -4389,6 +4510,12 @@
}
+static inline size_t
+QCBOREncode_Tell(QCBOREncodeContext *pMe)
+{
+ return UsefulOutBuf_GetEndPosition(&(pMe->OutBuf));
+}
+
/* ========================================================================
END OF PRIVATE INLINE IMPLEMENTATION
======================================================================== */
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 26325d8..855e840 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -6,7 +6,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
*
* Forked from qcbor_decode.h on 7/23/2020
* ========================================================================== */
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 4177010..25a92f4 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -44,8 +44,9 @@
when who what, where, why
-------- ---- ---------------------------------------------------
- 1/7/2024 llundblade Add UsefulInputBuf_Compare().
+ 08/08/2024 llundblade Add UsefulOutBuf_SubString().
21/05/2024 llundblade Comment formatting and some code tidiness.
+ 1/7/2024 llundblade Add UsefulInputBuf_Compare().
28/02/2022 llundblade Rearrange UsefulOutBuf_Compare().
19/11/2023 llundblade Add UsefulOutBuf_GetOutput().
19/11/2023 llundblade Add UsefulOutBuf_Swap().
@@ -418,6 +419,35 @@
}
+/*
+ * Public function -- see UsefulBuf.h
+ *
+ * Code Reviewers: THIS FUNCTION DOES POINTER MATH
+ */
+UsefulBufC UsefulOutBuf_SubString(UsefulOutBuf *pMe,
+ const size_t uStart,
+ const size_t uLen)
+{
+ const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
+
+ if(UsefulBuf_IsNULLC(Tmp)) {
+ return NULLUsefulBufC;
+ }
+
+ if(uStart > Tmp.len) {
+ return NULLUsefulBufC;
+ }
+
+ if(Tmp.len - uStart < uLen) {
+ return NULLUsefulBufC;
+ }
+
+ UsefulBufC SubString;
+ SubString.ptr = (const uint8_t *)Tmp.ptr + uStart;
+ SubString.len = uLen;
+
+ return SubString;
+}
/*
diff --git a/src/ieee754.c b/src/ieee754.c
index 40421ad..506d5e8 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -6,7 +6,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
*
* Created on 7/23/18
* ========================================================================== */
diff --git a/src/ieee754.h b/src/ieee754.h
index fed28f1..9d3a8f3 100644
--- a/src/ieee754.h
+++ b/src/ieee754.h
@@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
*
* Created on 7/23/18
* ========================================================================== */
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 41e6b21..21845f4 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -461,8 +461,8 @@
static QCBORError
DecodeNesting_DescendMapOrArray(QCBORDecodeNesting *pNesting,
- uint8_t uQCBORType,
- uint64_t uCount)
+ const uint8_t uQCBORType,
+ const uint16_t uCount)
{
QCBORError uError = QCBOR_SUCCESS;
@@ -474,21 +474,16 @@
/* Empty indefinite-length maps and arrays are handled elsewhere */
}
- /* Error out if arrays is too long to handle */
- if(uCount != QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH &&
- uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
- uError = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
- goto Done;
- }
+ /* Rely on check in QCBOR_Private_DecodeArrayOrMap() for definite-length
+ * arrays and maps that are too long */
uError = DecodeNesting_Descend(pNesting, uQCBORType);
if(uError != QCBOR_SUCCESS) {
goto Done;
}
- /* Fill in the new map/array level. Check above makes casts OK. */
- pNesting->pCurrent->u.ma.uCountCursor = (uint16_t)uCount;
- pNesting->pCurrent->u.ma.uCountTotal = (uint16_t)uCount;
+ pNesting->pCurrent->u.ma.uCountCursor = uCount;
+ pNesting->pCurrent->u.ma.uCountTotal = uCount;
DecodeNesting_ClearBoundedMode(pNesting);
@@ -1075,7 +1070,7 @@
static QCBORError
QCBOR_Private_DecodeArrayOrMap(const uint8_t uMode,
const int nMajorType,
- const uint64_t uItemCount,
+ uint64_t uItemCount,
const int nAdditionalInfo,
QCBORItem *pDecodedItem)
{
@@ -1108,28 +1103,20 @@
uReturn = QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED;
#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
} else {
+ /* ----- Definite-length array/map ----- */
+ if(uItemCount > (nMajorType == QCBOR_TYPE_MAP ? QCBOR_MAX_ITEMS_IN_MAP : QCBOR_MAX_ITEMS_IN_ARRAY)) {
+ uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
+ } else {
#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
- if(uMode == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
- /* ------ Definite-length map as array ------ */
-
- if(uItemCount > QCBOR_MAX_ITEMS_IN_ARRAY/2) {
- uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
- } else {
- /* cast OK because of check above */
- pDecodedItem->val.uCount = (uint16_t)uItemCount*2;
+ if(uMode == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
+ /* ------ Map as array ------ */
+ uItemCount *= 2;
}
-
- } else
#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
- {
- /* ------ Definite-length array/map ------ */
- if(uItemCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
- uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
- } else {
- /* cast OK because of check above */
- pDecodedItem->val.uCount = (uint16_t)uItemCount;
- }
+
+ /* cast OK because of check above */
+ pDecodedItem->val.uCount = (uint16_t)uItemCount;
}
}
@@ -1528,9 +1515,9 @@
QCBORItem *pDecodedItem)
{
QCBORError uReturn;
- int nMajorType = 0;
- uint64_t uArgument = 0;
- int nAdditionalInfo = 0;
+ int nMajorType = 0;
+ uint64_t uArgument = 0;
+ int nAdditionalInfo = 0;
memset(pDecodedItem, 0, sizeof(QCBORItem));
@@ -2311,8 +2298,8 @@
*/
QCBORError uDescendErr;
uDescendErr = DecodeNesting_DescendMapOrArray(&(pMe->nesting),
- pDecodedItem->uDataType,
- pDecodedItem->val.uCount);
+ pDecodedItem->uDataType,
+ pDecodedItem->val.uCount);
if(uDescendErr != QCBOR_SUCCESS) {
/* This error is probably a traversal error and it overrides
* the non-traversal error.
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index fa7f485..50ed8a3 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -1,35 +1,35 @@
-/*==============================================================================
- Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2024, Laurence Lundblade.
- Copyright (c) 2021, Arm Limited.
- All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors, nor the name "Laurence Lundblade" may be used to
- endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- =============================================================================*/
+/* ===========================================================================
+ * Copyright (c) 2016-2018, The Linux Foundation.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
+ * Copyright (c) 2021, Arm Limited.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors, nor the name "Laurence Lundblade" may be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ========================================================================= */
#include "qcbor/qcbor_encode.h"
@@ -115,10 +115,10 @@
Nesting_Increment(QCBORTrackNesting *pNesting)
{
#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
- if(1 >= QCBOR_MAX_ITEMS_IN_ARRAY - pNesting->pCurrentNesting->uCount) {
+ if(pNesting->pCurrentNesting->uCount >= QCBOR_MAX_ITEMS_IN_ARRAY) {
return QCBOR_ERR_ARRAY_TOO_LONG;
}
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
pNesting->pCurrentNesting->uCount++;
@@ -170,7 +170,7 @@
{
return pNesting->pCurrentNesting == &pNesting->pArrays[0] ? false : true;
}
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
@@ -227,7 +227,7 @@
*
* QCBOR_DISABLE_ENCODE_USAGE_GUARDS also disables the check for more
* than QCBOR_MAX_ITEMS_IN_ARRAY in an array. Since
- * QCBOR_MAX_ITEMS_IN_ARRAY is very large (65,535) it is very unlikely
+ * QCBOR_MAX_ITEMS_IN_ARRAY is very large (65,534) it is very unlikely
* to be reached. If it is reached, the count will wrap around to zero
* and CBOR that is not well formed will be produced, but there will
* be no buffers overrun and new security issues in the code.
@@ -450,7 +450,7 @@
nAdditionalInfo = CBOR_SIMPLE_BREAK;
} else
-#endif /* !QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
if (uArgument < CBOR_TWENTY_FOUR && uMinLen == 0) {
/* Simple case where argument is < 24 */
nAdditionalInfo = (int)uArgument;
@@ -529,7 +529,7 @@
}
#else
(void)Nesting_Increment(&(pMe->nesting));
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
}
@@ -580,7 +580,7 @@
/*
- * Public functions for adding signed integers. See qcbor/qcbor_encode.h
+ * Public function for adding signed integers. See qcbor/qcbor_encode.h
*/
void
QCBOREncode_AddInt64(QCBOREncodeContext *pMe, const int64_t nNum)
@@ -630,7 +630,7 @@
/*
- * Public functions for adding raw encoded CBOR. See qcbor/qcbor_encode.h
+ * Public function for adding raw encoded CBOR. See qcbor/qcbor_encode.h
*/
void
QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
@@ -759,7 +759,7 @@
QCBOREncode_Private_AddType7(pMe, (uint8_t)FloatResult.uSize, FloatResult.uValue);
}
-#endif /* !QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
@@ -1120,7 +1120,7 @@
}
QCBOREncode_CloseArray(pMe);
}
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
/**
@@ -1196,7 +1196,7 @@
*/
QCBOREncode_Private_OpenMapOrArray(pMe, uMajorType);
}
-#endif
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
/**
@@ -1231,7 +1231,7 @@
return true;
}
-#else /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#else /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
/* None of these checks are performed if the encode guards are
* turned off as they all relate to correct calling.
*
@@ -1241,14 +1241,14 @@
(void)uMajorType;
(void)pMe;
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
return false;
}
/**
- * @brief Insert the CBOR head for a map, array or wrapped bstr
+ * @brief Insert the CBOR head for a map, array or wrapped bstr.
*
* @param pMe QCBOR encoding context.
* @param uMajorType One of CBOR_MAJOR_TYPE_XXXX.
@@ -1643,7 +1643,7 @@
/*
- * Public functions for closing bstr wrapping. See qcbor/qcbor_encode.h
+ * Public function for closing bstr wrapping. See qcbor/qcbor_encode.h
*/
void
QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pMe,
@@ -1707,7 +1707,7 @@
* security hole, so no extra code or state is added to handle this
* condition.
*/
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
Nesting_Decrease(&(pMe->nesting));
Nesting_Decrement(&(pMe->nesting));
@@ -1729,7 +1729,7 @@
pMe->uError = QCBOR_ERR_OPEN_BYTE_STRING;
return;
}
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR);
}
@@ -1752,7 +1752,6 @@
#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-
/**
* @brief Semi-private method to close a map, array with indefinite length
*
@@ -1774,7 +1773,7 @@
QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK, CBOR_SIMPLE_BREAK, 0);
Nesting_Decrease(&(pMe->nesting));
}
-#endif
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
/*
@@ -1792,7 +1791,7 @@
pMe->uError = QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN;
goto Done;
}
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
*pEncodedCBOR = UsefulOutBuf_OutUBuf(&(pMe->OutBuf));
@@ -1802,7 +1801,7 @@
/*
- * Public functions to get size of the encoded result. See qcbor/qcbor_encode.h
+ * Public function to get size of the encoded result. See qcbor/qcbor_encode.h
*/
QCBORError
QCBOREncode_FinishGetSize(QCBOREncodeContext *pMe, size_t *puEncodedLen)
@@ -1817,3 +1816,28 @@
return nReturn;
}
+
+
+/*
+ * Public function to get substring of encoded-so-far. See qcbor/qcbor_encode.h
+ */
+UsefulBufC
+QCBOREncode_SubString(QCBOREncodeContext *pMe, const size_t uStart)
+{
+ if(pMe->uError) {
+ return NULLUsefulBufC;
+ }
+
+ /* An attempt was made to detect usage errors by comparing uStart
+ * to offsets of open arrays and maps in pMe->nesting, but it is
+ * not possible because there's not enough information in just
+ * the offset. It's not possible to known if Tell() was called before
+ * or after an Open(). To detect this error, the nesting level
+ * would also need to be known. This is not frequently used, so
+ * it is not worth adding this complexity.
+ */
+
+ const size_t uEnd = QCBOREncode_Tell(pMe);
+
+ return UsefulOutBuf_SubString(&(pMe->OutBuf), uStart, uEnd - uStart);
+}
diff --git a/src/qcbor_err_to_str.c b/src/qcbor_err_to_str.c
index 87c2b28..f9588e5 100644
--- a/src/qcbor_err_to_str.c
+++ b/src/qcbor_err_to_str.c
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
*
* Created on 3/21/20
* ========================================================================== */
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 6e47f3c..338e6db 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -127,6 +127,30 @@
goto Done;
}
+ Out = UsefulOutBuf_SubString(&UOB, 10, 8);
+ if(UsefulBuf_IsNULLC(Out) ||
+ UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL("unbounce"), Out) ||
+ UsefulOutBuf_GetError(&UOB)) {
+ szReturn = "SubString substring";
+ goto Done;
+ }
+
+ Out = UsefulOutBuf_SubString(&UOB, 0, Expected.len);
+ if(UsefulBuf_IsNULLC(Out) ||
+ UsefulBuf_Compare(Expected, Out) ||
+ UsefulOutBuf_GetError(&UOB)) {
+ szReturn = "SubString all";
+ goto Done;
+ }
+
+ Out = UsefulOutBuf_SubString(&UOB, Expected.len, 0);
+ if(UsefulBuf_IsNULLC(Out) ||
+ UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL(""), Out) ||
+ UsefulOutBuf_GetError(&UOB)) {
+ szReturn = "SubString empty";
+ goto Done;
+ }
+
/* Now test the size calculation mode */
UsefulOutBuf_Init(&UOB, SizeCalculateUsefulBuf);
@@ -246,7 +270,7 @@
return "Bad insertion point not caught";
- UsefulBuf_MAKE_STACK_UB(outBuf2,10);
+ UsefulBuf_MAKE_STACK_UB(outBuf2, 10);
UsefulOutBuf_Init(&UOB, outBuf2);
@@ -260,6 +284,29 @@
return "insert with data should have failed";
}
+ UsefulOutBuf_Init(&UOB, outBuf2);
+ UsefulOutBuf_AppendString(&UOB, "abc123");
+
+ UsefulBufC Out = UsefulOutBuf_SubString(&UOB, 7, 1);
+ if(!UsefulBuf_IsNULLC(Out)) {
+ return "SubString start should fail off end 1";
+ }
+ Out = UsefulOutBuf_SubString(&UOB, 5, 3);
+ if(!UsefulBuf_IsNULLC(Out)) {
+ return "SubString len should fail off end 2";
+ }
+ Out = UsefulOutBuf_SubString(&UOB, 0, 7);
+ if(!UsefulBuf_IsNULLC(Out)) {
+ return "SubString len should fail off end 3";
+ }
+ Out = UsefulOutBuf_SubString(&UOB, 7, 0);
+ if(!UsefulBuf_IsNULLC(Out)) {
+ return "SubString len should fail off end 4";
+ }
+ Out = UsefulOutBuf_SubString(&UOB, 6, 1);
+ if(!UsefulBuf_IsNULLC(Out)) {
+ return "SubString len should fail off end 5";
+ }
UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
diff --git a/test/float_tests.c b/test/float_tests.c
index d59241f..892942d 100644
--- a/test/float_tests.c
+++ b/test/float_tests.c
@@ -6,7 +6,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
*
* Created on 9/19/18
* ========================================================================= */
diff --git a/test/float_tests.h b/test/float_tests.h
index 427aa76..cfc2e6e 100644
--- a/test/float_tests.h
+++ b/test/float_tests.h
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 9/19/18
=============================================================================*/
diff --git a/test/half_to_double_from_rfc7049.h b/test/half_to_double_from_rfc7049.h
index 8e07dc2..aa3b4c3 100644
--- a/test/half_to_double_from_rfc7049.h
+++ b/test/half_to_double_from_rfc7049.h
@@ -6,7 +6,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 9/23/18
============================================================================*/
diff --git a/test/not_well_formed_cbor.h b/test/not_well_formed_cbor.h
index 5a213ef..c325768 100644
--- a/test/not_well_formed_cbor.h
+++ b/test/not_well_formed_cbor.h
@@ -7,7 +7,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 7/27/19
==============================================================================*/
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 202be19..8217053 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2296,9 +2296,61 @@
}
+/* These are just the item that open large maps and arrays, not
+ * the items in the array. This is sufficient to test the
+ * boundary condition. */
+static const uint8_t spLargeArrayFake[] = {
+ 0x99, 0xff, 0xfe};
+
+static const uint8_t spTooLargeArrayFake[] = {
+ 0x99, 0xff, 0xff};
+
+static const uint8_t spLargeMapFake[] = {
+ 0xb9, 0x7f, 0xff};
+
+static const uint8_t spTooLargeMapFake[] = {
+ 0xba, 0x00, 0x00, 0x80, 0x00};
+
int32_t ParseMapTest(void)
{
+ QCBORDecodeContext DCtx;
+ QCBORItem Item;
+ QCBORError uErr;
+
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLargeArrayFake),
+ QCBOR_DECODE_MODE_NORMAL);
+ uErr = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uErr != QCBOR_SUCCESS || Item.val.uCount != QCBOR_MAX_ITEMS_IN_ARRAY) {
+ return -100;
+ }
+
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLargeArrayFake),
+ QCBOR_DECODE_MODE_NORMAL);
+ uErr = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uErr != QCBOR_ERR_ARRAY_DECODE_TOO_LONG) {
+ return -101;
+ }
+
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLargeMapFake),
+ QCBOR_DECODE_MODE_NORMAL);
+ uErr = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uErr != QCBOR_SUCCESS || Item.val.uCount != QCBOR_MAX_ITEMS_IN_MAP) {
+ return -110;
+ }
+
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLargeMapFake),
+ QCBOR_DECODE_MODE_NORMAL);
+ uErr = QCBORDecode_GetNext(&DCtx, &Item);
+ if(uErr != QCBOR_ERR_ARRAY_DECODE_TOO_LONG) {
+ return -111;
+ }
+
+
// Parse a moderatly complex map structure very thoroughly
int32_t nResult = ParseMapTest1(QCBOR_DECODE_MODE_NORMAL);
if(nResult) {
@@ -11038,6 +11090,18 @@
return -107;
}
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+ QCBOR_DECODE_MODE_NORMAL);
+
+ UsefulBufC Xx = QCBORDecode_RetrieveUndecodedInput(&DCtx);
+ if(Xx.ptr != pValidMapEncoded) {
+ return -200;
+ }
+ if(Xx.len != sizeof(pValidMapEncoded)) {
+ return -201;
+ }
+
return 0;
}
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 88251ac..e2b8341 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -187,6 +187,11 @@
}
+ UsefulBuf Tmp = QCBOREncode_RetrieveOutputStorage(&EC);
+ if(Tmp.ptr != spBigBuf && Tmp.len != sizeof(spBigBuf)) {
+ return -111;
+ }
+
// Make another encoded message with the CBOR from the previous
// put into this one
UsefulBuf_MAKE_STACK_UB(MemoryForEncoded2, 20);
@@ -203,6 +208,8 @@
if(QCBOREncode_Finish(&EC, &Encoded2)) {
return -5;
}
+
+
/*
[ // 0 1:3
451, // 1 1:2
@@ -1136,10 +1143,9 @@
static const uint8_t spExpectedEncodedSimpleIndefiniteLength[] = {
0x9f, 0xf5, 0xf4, 0xf6, 0xf7, 0xbf, 0x65, 0x55, 0x4e, 0x44, 0x65, 0x66, 0xf7, 0xff, 0xff};
-int32_t SimpleValuesIndefiniteLengthTest1(void)
+int32_t IndefiniteLengthTest(void)
{
QCBOREncodeContext ECtx;
- int nReturn = 0;
QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
@@ -1158,13 +1164,38 @@
UsefulBufC ECBOR;
if(QCBOREncode_Finish(&ECtx, &ECBOR)) {
- nReturn = -1;
+ return -1;
}
- if(CheckResults(ECBOR, spExpectedEncodedSimpleIndefiniteLength))
+ if(CheckResults(ECBOR, spExpectedEncodedSimpleIndefiniteLength)) {
return -2;
+ }
- return(nReturn);
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
+ QCBOREncode_CloseArray(&ECtx);
+ if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+ return -3;
+ }
+
+ QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_OpenArray(&ECtx);
+ QCBOREncode_CloseArrayIndefiniteLength(&ECtx);
+ if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+ return -3;
+ }
+
+ QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
+ QCBOREncode_CloseMapIndefiniteLength(&ECtx);
+ if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+ return -3;
+ }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+ return 0;
}
#endif
@@ -2063,6 +2094,24 @@
return -11;
}
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ // Seventh test, erroneous cancel
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_CancelBstrWrap(&EC);
+ uErr = QCBOREncode_GetErrorState(&EC);
+ if(uErr != QCBOR_ERR_TOO_MANY_CLOSES) {
+ return -12;
+ }
+
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_OpenArray(&EC);
+ QCBOREncode_CancelBstrWrap(&EC);
+ uErr = QCBOREncode_GetErrorState(&EC);
+ if(uErr != QCBOR_ERR_CLOSE_MISMATCH) {
+ return -13;
+ }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
return 0;
}
@@ -2817,6 +2866,12 @@
return -11;
}
+ UsefulBuf Tmp;
+ Tmp = QCBOREncode_RetrieveOutputStorage(&EC);
+ if(Tmp.ptr != NULL && Tmp.len != UINT32_MAX) {
+ return -111;
+ }
+
/* ------ QCBOR_ERR_UNSUPPORTED -------- */
QCBOREncode_Init(&EC, Large);
QCBOREncode_OpenArray(&EC);
@@ -2873,6 +2928,37 @@
return -130;
}
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ /* ------ QCBOR_ERR_ARRAY_TOO_LONG -------- */
+ QCBOREncode_Init(&EC, Large);
+ QCBOREncode_OpenArray(&EC);
+ int i;
+ for(i = 0; i < QCBOR_MAX_ITEMS_IN_ARRAY; i++) {
+ QCBOREncode_AddInt64(&EC, 0);
+ }
+ if(QCBOREncode_GetErrorState(&EC)) {
+ return 250;
+ }
+ QCBOREncode_AddInt64(&EC, 0);
+ if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_ARRAY_TOO_LONG) {
+ return 251;
+ }
+
+ QCBOREncode_Init(&EC, Large);
+ QCBOREncode_OpenMap(&EC);
+ for(i = 0; i < QCBOR_MAX_ITEMS_IN_MAP; i++) {
+ QCBOREncode_AddInt64ToMapN(&EC, 0,0);
+ }
+ if(QCBOREncode_GetErrorState(&EC)) {
+ return 250;
+ }
+ QCBOREncode_AddInt64ToMapN(&EC, 0,0);
+ if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_ARRAY_TOO_LONG) {
+ return 251;
+ }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
return 0;
}
@@ -2881,26 +2967,34 @@
/*
[
4([-1, 3]),
+ [-1, 4],
4([-20, 4759477275222530853136]),
+ [2, 4759477275222530853136],
4([9223372036854775807, -4759477275222530853137]),
5([300, 100]),
+ [600, 200],
5([-20, 4759477275222530853136]),
- 5([-9223372036854775808, -4759477275222530853137])
- ]
+ [4, 4759477275222530853136],
+ 5([-9223372036854775808, -4759477275222530853137])]
+ ]
*/
static const uint8_t spExpectedExponentAndMantissaArray[] = {
- 0x86, 0xC4, 0x82, 0x20, 0x03, 0xC4, 0x82, 0x33,
- 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x10, 0xC4, 0x82, 0x1B, 0x7F,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
- 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0F, 0xC5, 0x82, 0x19, 0x01, 0x2C,
- 0x18, 0x64, 0xC5, 0x82, 0x33, 0xC2, 0x4A, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x10, 0xC5, 0x82, 0x3B, 0x7F, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0F};
-
+ 0x8A, 0xC4, 0x82, 0x20, 0x03, 0x82, 0x20, 0x04,
+ 0xC4, 0x82, 0x33, 0xC2, 0x4A, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x82,
+ 0x02, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x10, 0xC4, 0x82, 0x1B,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0F, 0xC5, 0x82, 0x19, 0x01, // TODO: adjust this back to value from master when better big num is ...
+ 0x2C, 0x18, 0x64, 0x82, 0x19, 0x02, 0x58, 0x18,
+ 0xC8, 0xC5, 0x82, 0x33, 0xC2, 0x4A, 0x01, 0x02,
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+ 0x82, 0x04, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0xC5, 0x82,
+ 0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0F}; // TODO: adjust this back to value from master when better big num is ...
/*
{
@@ -3114,10 +3208,14 @@
QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
QCBOREncode_OpenArray(&EC);
QCBOREncode_AddDecimalFraction(&EC, 3, -1); // 3 * (10 ^ -1)
+ QCBOREncode_AddTDecimalFraction(&EC, QCBOR_ENCODE_AS_BORROWED, 4, -1); // 3 * (10 ^ -1)
QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum , false, -20);
+ QCBOREncode_AddTDecimalFractionBigNum(&EC, QCBOR_ENCODE_AS_BORROWED, BigNum , false, 2);
QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum, true, INT64_MAX);
QCBOREncode_AddBigFloat(&EC, 100, 300);
+ QCBOREncode_AddTBigFloat(&EC, QCBOR_ENCODE_AS_BORROWED, 200, 600);
QCBOREncode_AddBigFloatBigNum(&EC, BigNum, false, -20);
+ QCBOREncode_AddTBigFloatBigNum(&EC, QCBOR_ENCODE_AS_BORROWED, BigNum, false, 4);
QCBOREncode_AddBigFloatBigNum(&EC, BigNum, true, INT64_MIN);
QCBOREncode_CloseArray(&EC);
@@ -3977,3 +4075,84 @@
}
#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
+
+int32_t SubStringTest(void)
+{
+ QCBOREncodeContext EC;
+ size_t uStart;
+ size_t uCurrent;
+ UsefulBufC SS;
+ UsefulBufC Encoded;
+ QCBORError uErr;
+
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_OpenArray(&EC);
+ uStart = QCBOREncode_Tell(&EC);
+ QCBOREncode_AddInt64(&EC, 0);
+ SS = QCBOREncode_SubString(&EC, uStart);
+ if(UsefulBuf_Compare(SS, (UsefulBufC){"\x00", 1})) {
+ return 1;
+ }
+
+ QCBOREncode_OpenArray(&EC);
+
+ QCBOREncode_CloseArray(&EC);
+ SS = QCBOREncode_SubString(&EC, uStart);
+ if(UsefulBuf_Compare(SS, (UsefulBufC){"\x00\x80", 2})) {
+ return 3;
+ }
+
+
+ /* Try it on a sequence */
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ uStart = QCBOREncode_Tell(&EC);
+ QCBOREncode_AddInt64(&EC, 1);
+ QCBOREncode_AddInt64(&EC, 1);
+ QCBOREncode_AddInt64(&EC, 1);
+ QCBOREncode_AddInt64(&EC, 1);
+ SS = QCBOREncode_SubString(&EC, uStart);
+ if(UsefulBuf_Compare(SS, (UsefulBufC){"\x01\x01\x01\x01", 4})) {
+ return 10;
+ }
+
+ uCurrent = QCBOREncode_Tell(&EC);
+ if(!UsefulBuf_IsNULLC(QCBOREncode_SubString(&EC, uCurrent+1))) {
+ return 11;
+ }
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ /* Now cause an error */
+ QCBOREncode_OpenMap(&EC);
+ QCBOREncode_CloseArray(&EC);
+ if(!UsefulBuf_IsNULLC(QCBOREncode_SubString(&EC, uStart))) {
+ return 15;
+ }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+
+ QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+ QCBOREncode_AddInt64(&EC, 1);
+ QCBOREncode_AddInt64(&EC, 1);
+ uStart = QCBOREncode_Tell(&EC);
+ QCBOREncode_OpenMap(&EC);
+ QCBOREncode_OpenMapInMapN(&EC, 3);
+ QCBOREncode_OpenArrayInMapN(&EC, 4);
+ QCBOREncode_AddInt64(&EC, 0);
+ QCBOREncode_CloseArray(&EC);
+ QCBOREncode_CloseMap(&EC);
+ QCBOREncode_CloseMap(&EC);
+ SS = QCBOREncode_SubString(&EC, uStart);
+ if(UsefulBuf_Compare(SS, (UsefulBufC){"\xA1\x03\xA1\x04\x81\x00", 6})) {
+ return 20;
+ }
+
+ uErr = QCBOREncode_Finish(&EC, &Encoded);
+ if(uErr) {
+ return 21;
+ }
+ if(UsefulBuf_Compare(Encoded, (UsefulBufC){"\x01\x01\xA1\x03\xA1\x04\x81\x00", 8})) {
+ return 22;
+ }
+
+ return 0;
+}
diff --git a/test/qcbor_encode_tests.h b/test/qcbor_encode_tests.h
index 1be5635..cb9f00f 100644
--- a/test/qcbor_encode_tests.h
+++ b/test/qcbor_encode_tests.h
@@ -108,7 +108,7 @@
/*
Encodes basic maps and arrays with indefinite length
*/
-int32_t SimpleValuesIndefiniteLengthTest1(void);
+int32_t IndefiniteLengthTest(void);
/*
@@ -204,4 +204,7 @@
#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
+int32_t SubStringTest(void);
+
+
#endif /* defined(__QCBOR__qcbor_encode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index 682d5e1..386da72 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -6,7 +6,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 9/30/18
=============================================================================*/
@@ -158,7 +158,7 @@
TEST_ENTRY_DISABLED(TooLargeInputTest),
TEST_ENTRY(EncodeErrorTests),
#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
- TEST_ENTRY(SimpleValuesIndefiniteLengthTest1),
+ TEST_ENTRY(IndefiniteLengthTest),
#endif
TEST_ENTRY(EncodeLengthThirtyoneTest),
TEST_ENTRY(CBORSequenceDecodeTests),
@@ -174,14 +174,14 @@
#endif /* QCBOR_DISABLE_TAGS */
TEST_ENTRY(ExponentAndMantissaEncodeTests),
#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
- TEST_ENTRY(BoolTest),
TEST_ENTRY(SortMapTest),
#if !defined(USEFULBUF_DISABLE_ALL_FLOAT) && !defined(QCBOR_DISABLE_PREFERRED_FLOAT)
TEST_ENTRY(CDETest),
TEST_ENTRY(DCBORTest),
#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
- TEST_ENTRY(ParseEmptyMapInMapTest),
-
+ TEST_ENTRY(ParseEmptyMapInMapTest),
+ TEST_ENTRY(SubStringTest),
+ TEST_ENTRY(BoolTest)
};
diff --git a/test/run_tests.h b/test/run_tests.h
index 6790710..370558a 100644
--- a/test/run_tests.h
+++ b/test/run_tests.h
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created 9/30/18
=============================================================================*/
diff --git a/ub-example.c b/ub-example.c
index 996cf3a..ec776dc 100644
--- a/ub-example.c
+++ b/ub-example.c
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 4/8/22
========================================================================== */
diff --git a/ub-example.h b/ub-example.h
index 131c807..93449f4 100644
--- a/ub-example.h
+++ b/ub-example.h
@@ -5,7 +5,7 @@
SPDX-License-Identifier: BSD-3-Clause
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
Created on 4/8/22
========================================================================== */