This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-mcumgr.git

commit c42d4ca3b6114600cd2b9a0b57887bf146c3e077
Author: Szymon Janc <[email protected]>
AuthorDate: Wed Oct 7 15:56:36 2026 +0200

    cborattr: Fix string attributes decoding
    
    Fix several issues with decoding of string attributes:
     - errors from decoding attribute value were overwritten when advancing
       to next value and not reported to caller
     - byte string length was set to string length even if string was not
       copied due to too small buffer
     - text string filling whole buffer was not NUL terminated
     - omitted text and byte string attributes were left uninitialized
    
    Text strings now always have space reserved for terminating NUL and are
    set to empty on error. Byte string length is set to 0 on error.
    
    Assisted-by: Claude:claude-opus-5-5
---
 cborattr/src/cborattr.c | 54 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c
index 0a9ef83..3c4c49e 100644
--- a/cborattr/src/cborattr.c
+++ b/cborattr/src/cborattr.c
@@ -245,6 +245,16 @@ cbor_internal_read_object(CborValue *root_value,
                 case CborAttrBooleanType:
                     memcpy(lptr, &cursor->dflt.boolean, sizeof(bool));
                     break;
+                case CborAttrTextStringType:
+                    if (cursor->len > 0) {
+                        *(char *)lptr = '\0';
+                    }
+                    break;
+                case CborAttrByteStringType:
+                    if (cursor->addr.bytestring.len) {
+                        *cursor->addr.bytestring.len = 0;
+                    }
+                    break;
 #if FLOAT_SUPPORT
                 case CborAttrHalfFloatType:
                     memcpy(lptr, &cursor->dflt.halffloat, sizeof(uint16_t));
@@ -274,14 +284,16 @@ cbor_internal_read_object(CborValue *root_value,
     while (cbor_value_is_valid(&cur_value) && !err) {
         /* get the attribute */
         if (cbor_value_is_text_string(&cur_value)) {
-            if (cbor_value_calculate_string_length(&cur_value, &len) == 0) {
-                if (len > CBORATTR_MAX_SIZE) {
-                    err |= CborErrorDataTooLarge;
-                    break;
-                }
-                err |= cbor_value_copy_text_string(&cur_value, attrbuf, &len,
-                                                     NULL);
+            err |= cbor_value_calculate_string_length(&cur_value, &len);
+            if (err) {
+                break;
             }
+            if (len > CBORATTR_MAX_SIZE) {
+                err |= CborErrorDataTooLarge;
+                break;
+            }
+            err |= cbor_value_copy_text_string(&cur_value, attrbuf, &len,
+                                               NULL);
 
             /* at least get the type of the next value so we can match the
              * attribute name and type for a perfect match */
@@ -342,15 +354,29 @@ cbor_internal_read_object(CborValue *root_value,
 #endif
             case CborAttrByteStringType: {
                 size_t len = cursor->len;
-                err |= cbor_value_copy_byte_string(&cur_value, lptr,
-                                                   &len, NULL);
-                *cursor->addr.bytestring.len = len;
+                CborError copy_err;
+
+                copy_err = cbor_value_copy_byte_string(&cur_value, lptr,
+                                                       &len, NULL);
+                err |= copy_err;
+                /* On error len is set to string length, not copied length */
+                *cursor->addr.bytestring.len = copy_err ? 0 : len;
                 break;
             }
             case CborAttrTextStringType: {
-                size_t len = cursor->len;
-                err |= cbor_value_copy_text_string(&cur_value, lptr,
-                                                   &len, NULL);
+                size_t len;
+                CborError copy_err;
+
+                if (cursor->len < 1) {
+                    err |= CborErrorOutOfMemory;
+                    break;
+                }
+                /* Reserve space for terminating NUL */
+                len = cursor->len - 1;
+                copy_err = cbor_value_copy_text_string(&cur_value, lptr,
+                                                       &len, NULL);
+                err |= copy_err;
+                ((char *)lptr)[copy_err ? 0 : len] = '\0';
                 break;
             }
             case CborAttrArrayType:
@@ -364,7 +390,7 @@ cbor_internal_read_object(CborValue *root_value,
                 err |= CborErrorIllegalType;
             }
         }
-        err = cborattr_advance(&cur_value);
+        err |= cborattr_advance(&cur_value);
     }
     if (!err) {
         /* that should be it for this container */

Reply via email to