msgbuf: Add pldm_msgbuf_extract_uint*_to_size APIs
Add pldm_msgbuf_extract_uint8_to_size(),
pldm_msgbuf_extract_uint16_to_size() and
pldm_msgbuf_extract_uint32_to_size() APIs to msgbuf API list. These are
the extractors which extract uint8_t/uint16_t/uint32_t to the size_t
destination. We mostly use size_t as the type to hold object size, but
extracting data to a size_t variable has not been properly supported.
These new APIs can bypass this limitation.
Example:
Extract from buffer the length of a variable length data represented by
`variable_field` struct, which has a field of size_t to represent
length.
Change-Id: I89f2600602bacf39f1f915a3496231dcc63fd6aa
Signed-off-by: Chau Ly <chaul@amperecomputing.com>
diff --git a/src/msgbuf.h b/src/msgbuf.h
index d33d8e9..a0e1204 100644
--- a/src/msgbuf.h
+++ b/src/msgbuf.h
@@ -1309,6 +1309,99 @@
return pldm__msgbuf_insert_array_void(dst, len, utf16, len);
}
+/**
+ * @brief pldm_msgbuf uint8_t extractor for a size_t
+ *
+ * @param[in,out] ctx - pldm_msgbuf context for extractor
+ * @param[out] dst - destination of extracted value
+ *
+ * @return 0 if buffer accesses were in-bounds,
+ * -EINVAL if dst pointer is invalid,
+ * -EOVERFLOW is the buffer was out of bound.
+ */
+#define pldm_msgbuf_extract_uint8_to_size(ctx, dst) \
+ pldm__msgbuf_extract_uint8_to_size(ctx, &(dst))
+LIBPLDM_CC_NONNULL
+LIBPLDM_CC_ALWAYS_INLINE int
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+pldm__msgbuf_extract_uint8_to_size(struct pldm_msgbuf *ctx, size_t *dst)
+{
+ uint8_t value;
+ int rc;
+
+ rc = pldm__msgbuf_extract_uint8(ctx, &value);
+ if (rc) {
+ return rc;
+ }
+
+ static_assert(SIZE_MAX >= UINT8_MAX, "Invalid promotion");
+
+ *dst = value;
+ return 0;
+}
+
+/**
+ * @brief pldm_msgbuf uint16_t extractor for a size_t
+ *
+ * @param[in,out] ctx - pldm_msgbuf context for extractor
+ * @param[out] dst - destination of extracted value
+ *
+ * @return 0 if buffer accesses were in-bounds,
+ * -EINVAL if dst pointer is invalid,
+ * -EOVERFLOW is the buffer was out of bound.
+ */
+#define pldm_msgbuf_extract_uint16_to_size(ctx, dst) \
+ pldm__msgbuf_extract_uint16_to_size(ctx, &(dst))
+LIBPLDM_CC_NONNULL
+LIBPLDM_CC_ALWAYS_INLINE int
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+pldm__msgbuf_extract_uint16_to_size(struct pldm_msgbuf *ctx, size_t *dst)
+{
+ uint16_t value;
+ int rc;
+
+ rc = pldm__msgbuf_extract_uint16(ctx, &value);
+ if (rc) {
+ return rc;
+ }
+
+ static_assert(SIZE_MAX >= UINT16_MAX, "Invalid promotion");
+
+ *dst = value;
+ return 0;
+}
+
+/**
+ * @brief pldm_msgbuf uint32_t extractor for a size_t
+ *
+ * @param[in,out] ctx - pldm_msgbuf context for extractor
+ * @param[out] dst - destination of extracted value
+ *
+ * @return 0 if buffer accesses were in-bounds,
+ * -EINVAL if dst pointer is invalid,
+ * -EOVERFLOW is the buffer was out of bound.
+ */
+#define pldm_msgbuf_extract_uint32_to_size(ctx, dst) \
+ pldm__msgbuf_extract_uint32_to_size(ctx, &(dst))
+LIBPLDM_CC_NONNULL
+LIBPLDM_CC_ALWAYS_INLINE int
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+pldm__msgbuf_extract_uint32_to_size(struct pldm_msgbuf *ctx, size_t *dst)
+{
+ uint32_t value;
+ int rc;
+
+ rc = pldm__msgbuf_extract_uint32(ctx, &value);
+ if (rc) {
+ return rc;
+ }
+
+ static_assert(SIZE_MAX >= UINT32_MAX, "Invalid promotion");
+
+ *dst = value;
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif