Fixes for MIME encoding
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index a266be7..1155fdb 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -129,7 +129,7 @@
E776E096214AE0C700E67947 /* cmd_line_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmd_line_main.c; sourceTree = "<group>"; };
E776E161214EE19C00E67947 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
E78C91DE240C90C100F4CECE /* qcbor_decode.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_decode.h; path = inc/qcbor/qcbor_decode.h; sourceTree = "<group>"; tabWidth = 3; };
- E78C91DF240C90C100F4CECE /* qcbor_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qcbor_common.h; path = inc/qcbor/qcbor_common.h; sourceTree = "<group>"; };
+ E78C91DF240C90C100F4CECE /* qcbor_common.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_common.h; path = inc/qcbor/qcbor_common.h; sourceTree = "<group>"; tabWidth = 3; };
E78C91E0240C90C100F4CECE /* qcbor_private.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_private.h; path = inc/qcbor/qcbor_private.h; sourceTree = "<group>"; tabWidth = 3; };
E78C91E1240C90C100F4CECE /* qcbor_encode.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_encode.h; path = inc/qcbor/qcbor_encode.h; sourceTree = "<group>"; tabWidth = 3; };
/* End PBXFileReference section */
diff --git a/README.md b/README.md
index 7678f53..1c76d93 100644
--- a/README.md
+++ b/README.md
@@ -176,6 +176,17 @@
maps and arrays without the caller having to do anything. This includes
mixed definite and indefinte maps and arrays.
+### Uncompatible Changes
+
+Encoding of MIME tags now uses tag 257 instead of 36. Tag 257 accommodates
+binary and text-based MIME messages where tag 36 does not. Decoding
+supports either.
+
+The number of nested tags on a data item is limited to four. Previously it was
+unlimited.
+
+Some of the error codes have changed.
+
## Floating Point Support
By default, all QCBOR floating-point features are enabled. This includes
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 0951bd5..d72a002 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -1258,19 +1258,28 @@
/**
- @brief MIME encoded text to the encoded output.
+ @brief MIME encoded data to the encoded output.
- @param[in] pCtx The encoding context to add the MIME data to.
- @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
- @param[in] MIMEData Pointer and length of the MIME Data.
+ @param[in] pCtx The encoding context to add the MIME data to.
+ @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
+ @ref QCBOR_ENCODE_AS_BORROWED.
+ @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. Note
- that this only supports text-format MIME. Binary MIME is not
- supported.
+ (https://tools.ietf.org/html/rfc2045) including the headers.
- It is output as CBOR major type 3, a text string, with tag
- @ref CBOR_TAG_MIME indicating the text string is MIME data.
+ 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
+ outputs tag 257, not tag 36, as it can carry any type of MIME binary,
+ 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
+
+ Previous versions of QCBOR, those before spiffy decode, output tag
+ 36. Decoding supports both tag 36 and 257. (if the old behavior with
+ tag 36 is needed, copy the inline functions below and change the tag
+ number).
+
+ See also QCBORDecode_GetMIMEMessage() and
+ @ref QCBOR_TYPE_BINARY_MIME.
*/
static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
uint8_t uTagRequirement,
@@ -2772,11 +2781,10 @@
static inline void
QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
{
- // TODO: add support for binary MIME.
if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
- QCBOREncode_AddTag(pMe, CBOR_TAG_MIME);
+ QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
}
- QCBOREncode_AddText(pMe, MIMEData);
+ QCBOREncode_AddBytes(pMe, MIMEData);
}
static inline void
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 7809733..cbfbe00 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -1386,8 +1386,7 @@
@param[in] pCtx The decode context.
@param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
@param[out] pMessage The decoded regular expression.
- @param[out] pbIsNot7Bit @c true if MIME is binary or 8-bit.
-
+ @param[out] pbIsTag257 @c true if tag was 257. May be @c NULL.
This decodes the standard CBOR MIME and binary MIME tags, integer tag
numbers of 36 or 257, or encoded CBOR that is not a tag, that is a
@@ -1399,34 +1398,34 @@
The MIME message itself is not parsed.
- This decodes both tag 36 and 257. If it is tag 257, pbIsNot7Bit
- is @c true. While it is clear that tag 36 can't contain,
- binary or 8-bit MIME, it is probably legal for tag 257
- to contain 7-bit MIME. Hopefully in most uses the
- Content-Transfer-Encoding header is present and the
- contents of pbIsNot7Bit can be ignored. It may be NULL.
+ This decodes both tag 36 and 257. If it is tag 257, pbIsTag257
+ is @c true. The difference between the two is that
+ tag 36 is utf8 and tag 257 is a byte string that can
+ carry binary MIME. QCBOR processes them exactly
+ the same. Possibly the difference can be ignored.
+ NULL can be passed to have no value returned.
See also @ref CBOR_TAG_MIME, @ref CBOR_TAG_BINARY_MIME,
- QCBOREncode_AddMIMEData(), @ref QCBOR_TYPE_MIME and
+ QCBOREncode_AddTMIMEData(), @ref QCBOR_TYPE_MIME and
@ref QCBOR_TYPE_BINARY_MIME.
*/
static void QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pCtx,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit);
+ bool *pbIsTag257);
static void QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pCtx,
int64_t nLabel,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit);
+ bool *pbIsTag257);
static void QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pCtx,
const char *szLabel,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit);
+ bool *pbIsTag257);
/**
@brief Decode the next item as a UUID
@@ -1885,7 +1884,7 @@
QCBORError QCBORDecode_GetMIMEInternal(uint8_t uTagRequirement,
const QCBORItem *pItem,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit);
+ bool *pbIsTag257);
@@ -2219,7 +2218,7 @@
QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit)
+ bool *pbIsTag257)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
// Already in error state, do nothing
@@ -2236,7 +2235,7 @@
pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
&Item,
pMessage,
- pbIsNot7Bit);
+ pbIsTag257);
}
static inline void
@@ -2244,7 +2243,7 @@
int64_t nLabel,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit)
+ bool *pbIsTag257)
{
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
@@ -2253,7 +2252,7 @@
pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
&Item,
pMessage,
- pbIsNot7Bit);
+ pbIsTag257);
}
}
@@ -2262,7 +2261,7 @@
const char *szLabel,
uint8_t uTagRequirement,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit)
+ bool *pbIsTag257)
{
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
@@ -2271,7 +2270,7 @@
pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
&Item,
pMessage,
- pbIsNot7Bit);
+ pbIsTag257);
}
}
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 36f1d9c..e903317 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -3662,7 +3662,7 @@
QCBORError QCBORDecode_GetMIMEInternal(uint8_t uTagRequirement,
const QCBORItem *pItem,
UsefulBufC *pMessage,
- bool *pbIsNot7Bit)
+ bool *pbIsTag257)
{
const TagSpecification TagSpecText =
{
@@ -3681,14 +3681,14 @@
if(CheckTagRequirement(TagSpecText, pItem) == QCBOR_SUCCESS) {
*pMessage = pItem->val.string;
- if(pbIsNot7Bit != NULL) {
- *pbIsNot7Bit = false;
+ if(pbIsTag257 != NULL) {
+ *pbIsTag257 = false;
}
uReturn = QCBOR_SUCCESS;
} else if(CheckTagRequirement(TagSpecBinary, pItem) == QCBOR_SUCCESS) {
*pMessage = pItem->val.string;
- if(pbIsNot7Bit != NULL) {
- *pbIsNot7Bit = true;
+ if(pbIsTag257 != NULL) {
+ *pbIsTag257 = true;
}
uReturn = QCBOR_SUCCESS;
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 2bc030c..c573a4b 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -316,8 +316,8 @@
0x1c, 0x59, 0x57, 0x35, 0x35, 0x49, 0x47, 0x4e, 0x68, 0x63,
0x6d, 0x35, 0x68, 0x62, 0x43, 0x42, 0x77, 0x62, 0x47, 0x56,
0x68, 0x63, 0x33, 0x56, 0x79, 0x5a, 0x51, 0x3d, 0x3d, 0xd8,
- 0x23, 0x67, 0x5b, 0x5e, 0x61, 0x62, 0x63, 0x5d, 0x2b, 0xd8,
- 0x24, 0x79, 0x01, 0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56,
+ 0x23, 0x67, 0x5b, 0x5e, 0x61, 0x62, 0x63, 0x5d, 0x2b, 0xd9,
+ 0x01, 0x01, 0x59, 0x01, 0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e,
0x30, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,
0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74,
@@ -376,7 +376,7 @@
0x79, 0x5a, 0x53, 0x34, 0x3d, 0x64, 0x70, 0x6f, 0x70, 0x6f,
0xd8, 0x23, 0x68, 0x31, 0x30, 0x30, 0x5c, 0x73, 0x2a, 0x6d,
0x6b, 0x38, 0x32, 0xd8, 0x23, 0x66, 0x70, 0x65, 0x72, 0x6c,
- 0x5c, 0x42, 0x63, 0x4e, 0x65, 0x64, 0xd8, 0x24, 0x79, 0x01,
+ 0x5c, 0x42, 0x63, 0x4e, 0x65, 0x64, 0xd9, 0x01, 0x01, 0x59, 0x01,
0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x30, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70,
@@ -411,7 +411,7 @@
0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x65, 0x78,
0x74, 0x0a, 0x0a, 0x2d, 0x2d, 0x58, 0x58, 0x58, 0x58, 0x62,
0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x20, 0x74, 0x65,
- 0x78, 0x74, 0x2d, 0x2d, 0x0a, 0xd8, 0x24, 0x79, 0x01, 0x57,
+ 0x78, 0x74, 0x2d, 0x2d, 0x0a, 0xd9, 0x01, 0x01, 0x59, 0x01, 0x57,
0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x30, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65,