msgbuf: Harden pldm_msgbuf_{insert,extract}_array()

Review of some proposed APIs suggested that correct use of the
pldm_msgbuf_{insert,extract}_array() helpers was more difficult that it
should be. In the three-parameter form, it was too tempting to provide
the length to extract as parsed out of a PLDM message. The intended
use was that the length parameter represented the length of the
user-provided data buffer.

Instead, move to a four-parameter form, provide reasonable documentation
for how these APIs should be used, fix all the call-sites, and deprecate
some existing unsafe APIs.

Change-Id: If58e5574600e80b354f383554283c4eda5d7234c
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a6225b..653f68a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,15 @@
 6. pdr: Add related decode_entity_auxiliary_names_pdr() APIs
 7. fw_update: Add encode req & decode resp for get_downstream_fw_params
 8. platform: Add decode_pldm_platform_cper_event() API
+9. decode_get_pdr_repository_info_resp_safe()
+
+   Replaces decode_get_pdr_repository_info_resp() as discussed in the
+   `Deprecated` section below
+
+10. decode_get_pdr_resp_safe()
+
+    Replaces decode_get_pdr_resp() as discussed in the `Deprecated` section
+    below
 
 ### Changed
 
@@ -67,6 +76,17 @@
 
 [clang-rename]: https://clang.llvm.org/extra/clang-rename.html
 
+2. `decode_get_pdr_repository_info_resp()`
+
+   Users should move to `decode_get_pdr_repository_info_resp_safe()` which
+   eliminates the opportunity for buffer overruns when extracting objects from
+   the message.
+
+3. `decode_get_pdr_resp()`
+
+   Users should move to `decode_get_pdr_resp_safe()` which reduces the
+   invocation tedium and improves memory safety over `decode_get_pdr_resp()`.
+
 ### Removed
 
 1. IBM OEM header compatibility symlinks.
diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h
index 95c90eb..5f23983 100644
--- a/include/libpldm/platform.h
+++ b/include/libpldm/platform.h
@@ -1577,6 +1577,18 @@
 	uint32_t *repository_size, uint32_t *largest_record_size,
 	uint8_t *data_transfer_handle_timeout);
 
+/** @brief Decode GetPDRRepositoryInfo response data
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] resp - The response structure to populate with the extracted message data. Output member values are host-endian.
+ *
+ *  @return 0 on success, a negative errno value on failure.
+ */
+int decode_get_pdr_repository_info_resp_safe(
+	const struct pldm_msg *msg, size_t payload_length,
+	struct pldm_pdr_repository_info_resp *resp);
+
 /* GetPDR */
 
 /** @brief Create a PLDM request message for GetPDR
@@ -1634,6 +1646,26 @@
 			uint8_t *record_data, size_t record_data_length,
 			uint8_t *transfer_crc);
 
+/** @brief Decode GetPDR response data
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] resp - The response structure into which the message will be unpacked
+ *  @param[in] resp_len - The size of the resp object in memory
+ *  @param[out] transfer_crc - A CRC-8 for the overall PDR. This is present only
+ *        in the last part of a PDR being transferred
+ *  @return 0 on success, otherwise, a negative errno value on failure
+ */
+int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
+			     struct pldm_get_pdr_resp *resp, size_t resp_len,
+			     uint8_t *transfer_crc);
+
 /* SetStateEffecterStates */
 
 /** @brief Create a PLDM request message for SetStateEffecterStates
diff --git a/src/compiler.h b/src/compiler.h
index 3657471..af392b1 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -13,11 +13,14 @@
 		      "`always_inline` attribute is required");
 	static_assert(__has_attribute(unused),
 		      "`unused` attribute is required");
+	static_assert(__has_attribute(warn_unused_result),
+		      "`warn_unused_result` attribute is required");
 	int compliance;
 } pldm_required_attributes __attribute__((unused));
 
-#define LIBPLDM_CC_ALWAYS_INLINE __attribute__((always_inline)) static inline
-#define LIBPLDM_CC_UNUSED	 __attribute__((unused))
+#define LIBPLDM_CC_ALWAYS_INLINE      __attribute__((always_inline)) static inline
+#define LIBPLDM_CC_UNUSED	      __attribute__((unused))
+#define LIBPLDM_CC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 
 // NOLINTBEGIN(bugprone-macro-parentheses)
 /**
diff --git a/src/dsp/base.h b/src/dsp/base.h
index 0e2c1a0..1124b00 100644
--- a/src/dsp/base.h
+++ b/src/dsp/base.h
@@ -4,6 +4,7 @@
 
 /* Internal functions */
 
+#include "compiler.h"
 #include <libpldm/base.h>
 
 int pack_pldm_header_errno(const struct pldm_header_info *hdr,
@@ -12,4 +13,11 @@
 int unpack_pldm_header_errno(const struct pldm_msg_hdr *msg,
 			     struct pldm_header_info *hdr);
 
+LIBPLDM_CC_ALWAYS_INLINE
+int pldm_msg_has_error(const struct pldm_msg *msg, size_t payload_length)
+{
+	static_assert(PLDM_SUCCESS == 0, "Rework required");
+	return payload_length < 1 ? 0 : msg->payload[0];
+}
+
 #endif
diff --git a/src/dsp/firmware_update.c b/src/dsp/firmware_update.c
index 80310b2..61bb953 100644
--- a/src/dsp/firmware_update.c
+++ b/src/dsp/firmware_update.c
@@ -1152,8 +1152,14 @@
 	if (rc < 0) {
 		return rc;
 	}
-	pldm_msgbuf_extract_array(buf, entry->active_comp_release_date,
-				  PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN);
+	rc = pldm_msgbuf_extract_array(buf,
+				       PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
+				       entry->active_comp_release_date,
+				       sizeof(entry->active_comp_release_date));
+	if (rc < 0) {
+		return rc;
+	}
+
 	// Fill the last byte with NULL character
 	entry->active_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN] =
 		'\0';
@@ -1164,8 +1170,15 @@
 	if (rc < 0) {
 		return rc;
 	}
-	pldm_msgbuf_extract_array(buf, entry->pending_comp_release_date,
-				  PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN);
+
+	rc = pldm_msgbuf_extract_array(
+		buf, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
+		entry->pending_comp_release_date,
+		sizeof(entry->pending_comp_release_date));
+	if (rc < 0) {
+		return rc;
+	}
+
 	// Fill the last byte with NULL character
 	entry->pending_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN] =
 		'\0';
@@ -1218,10 +1231,20 @@
 		return rc;
 	}
 
-	pldm_msgbuf_extract_array(buf, active, entry->active_comp_ver_str_len);
+	rc = pldm_msgbuf_extract_array(buf, entry->active_comp_ver_str_len,
+				       active, entry->active_comp_ver_str_len);
+	if (rc < 0) {
+		return rc;
+	}
+
 	active[entry->active_comp_ver_str_len] = '\0';
-	pldm_msgbuf_extract_array(buf, pending,
-				  entry->pending_comp_ver_str_len);
+	rc = pldm_msgbuf_extract_array(buf, entry->pending_comp_ver_str_len,
+				       pending,
+				       entry->pending_comp_ver_str_len);
+	if (rc < 0) {
+		return rc;
+	}
+
 	pending[entry->pending_comp_ver_str_len] = '\0';
 
 	entry->active_comp_ver_str = active;
diff --git a/src/dsp/platform.c b/src/dsp/platform.c
index 6ef1061..e355792 100644
--- a/src/dsp/platform.c
+++ b/src/dsp/platform.c
@@ -421,7 +421,7 @@
 	return PLDM_SUCCESS;
 }
 
-LIBPLDM_ABI_STABLE
+LIBPLDM_ABI_DEPRECATED
 int decode_get_pdr_repository_info_resp(
 	const struct pldm_msg *msg, size_t payload_length,
 	uint8_t *completion_code, uint8_t *repository_state,
@@ -457,8 +457,20 @@
 		return PLDM_ERROR_INVALID_DATA;
 	}
 
-	pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
-	pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
+	/* NOTE: Memory safety */
+	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
+				       PLDM_TIMESTAMP104_SIZE);
+	if (rc) {
+		return rc;
+	}
+
+	/* NOTE: Memory safety */
+	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
+				       oem_update_time, PLDM_TIMESTAMP104_SIZE);
+	if (rc) {
+		return rc;
+	}
+
 	pldm_msgbuf_extract_p(buf, record_count);
 	pldm_msgbuf_extract_p(buf, repository_size);
 	pldm_msgbuf_extract_p(buf, largest_record_size);
@@ -467,6 +479,61 @@
 	return pldm_msgbuf_destroy(buf);
 }
 
+LIBPLDM_ABI_TESTING
+int decode_get_pdr_repository_info_resp_safe(
+	const struct pldm_msg *msg, size_t payload_length,
+	struct pldm_pdr_repository_info_resp *resp)
+{
+	struct pldm_msgbuf _buf;
+	struct pldm_msgbuf *buf = &_buf;
+	int rc;
+
+	if (msg == NULL || resp == NULL) {
+		return -EINVAL;
+	}
+
+	rc = pldm_msg_has_error(msg, payload_length);
+	if (rc) {
+		resp->completion_code = rc;
+		return 0;
+	}
+
+	rc = pldm_msgbuf_init_errno(buf,
+				    PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
+				    msg->payload, payload_length);
+	if (rc) {
+		return rc;
+	}
+
+	rc = pldm_msgbuf_extract(buf, resp->completion_code);
+	if (rc) {
+		return rc;
+	}
+
+	pldm_msgbuf_extract(buf, resp->repository_state);
+
+	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
+				       resp->update_time,
+				       sizeof(resp->update_time));
+	if (rc) {
+		return rc;
+	}
+
+	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
+				       resp->oem_update_time,
+				       sizeof(resp->oem_update_time));
+	if (rc) {
+		return rc;
+	}
+
+	pldm_msgbuf_extract(buf, resp->record_count);
+	pldm_msgbuf_extract(buf, resp->repository_size);
+	pldm_msgbuf_extract(buf, resp->largest_record_size);
+	pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
+
+	return pldm_msgbuf_destroy_consumed(buf);
+}
+
 LIBPLDM_ABI_STABLE
 int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
 		       uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
@@ -503,7 +570,7 @@
 	return PLDM_SUCCESS;
 }
 
-LIBPLDM_ABI_STABLE
+LIBPLDM_ABI_DEPRECATED
 int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
 			uint8_t *completion_code, uint32_t *next_record_hndl,
 			uint32_t *next_data_transfer_hndl,
@@ -544,7 +611,12 @@
 		if (record_data_length < *resp_cnt) {
 			return PLDM_ERROR_INVALID_LENGTH;
 		}
-		pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
+		/* NOTE: Memory safety */
+		rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
+					       *resp_cnt);
+		if (rc) {
+			return rc;
+		}
 	}
 
 	if (*transfer_flag == PLDM_END) {
@@ -554,6 +626,59 @@
 	return pldm_msgbuf_destroy(buf);
 }
 
+LIBPLDM_ABI_TESTING
+int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
+			     struct pldm_get_pdr_resp *resp, size_t resp_len,
+			     uint8_t *transfer_crc)
+{
+	struct pldm_msgbuf _buf;
+	struct pldm_msgbuf *buf = &_buf;
+	int rc;
+
+	if (msg == NULL || resp == NULL || transfer_crc == NULL) {
+		return -EINVAL;
+	}
+
+	rc = pldm_msg_has_error(msg, payload_length);
+	if (rc) {
+		resp->completion_code = rc;
+		return 0;
+	}
+
+	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
+				    msg->payload, payload_length);
+	if (rc) {
+		return rc;
+	}
+
+	pldm_msgbuf_extract(buf, resp->completion_code);
+	pldm_msgbuf_extract(buf, resp->next_record_handle);
+	pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
+
+	rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
+	if (rc) {
+		return rc;
+	}
+
+	rc = pldm_msgbuf_extract(buf, resp->response_count);
+	if (rc) {
+		return rc;
+	}
+
+	rc = pldm_msgbuf_extract_array(
+		buf, resp->response_count, resp->record_data,
+		resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
+	if (rc) {
+		return rc;
+	}
+
+	if (resp->transfer_flag == PLDM_END) {
+		pldm_msgbuf_extract_p(buf, transfer_crc);
+	}
+
+	return pldm_msgbuf_destroy_consumed(buf);
+}
+
 LIBPLDM_ABI_STABLE
 int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
 					  size_t payload_length,
@@ -1057,7 +1182,11 @@
 	pldm_msgbuf_insert(buf, event_data_size);
 
 	if ((event_data_size > 0) && event_data) {
-		pldm_msgbuf_insert_array(buf, event_data, event_data_size);
+		rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
+					      event_data_size);
+		if (rc) {
+			return rc;
+		}
 	}
 
 	if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
@@ -2768,7 +2897,10 @@
 
 	for (i = 0; i < pdr->name_string_count; i++) {
 		pldm_msgbuf_span_string_ascii(src, NULL, NULL);
-		pldm_msgbuf_copy_string_utf16(dst, src);
+		rc = pldm_msgbuf_copy_string_utf16(dst, src);
+		if (rc) {
+			return rc;
+		}
 	}
 
 	rc = pldm_msgbuf_destroy_consumed(src);
@@ -2783,7 +2915,10 @@
 	}
 
 	for (i = 0; i < pdr->name_string_count; i++) {
-		pldm_msgbuf_copy_string_ascii(dst, src);
+		rc = pldm_msgbuf_copy_string_ascii(dst, src);
+		if (rc) {
+			return rc;
+		}
 		pldm_msgbuf_span_string_utf16(src, NULL, NULL);
 	}
 
@@ -2902,8 +3037,12 @@
 		return -EOVERFLOW;
 	}
 
-	pldm_msgbuf_extract_array_uint8(buf, cper_event->event_data,
-					cper_event->event_data_length);
+	rc = pldm_msgbuf_extract_array_uint8(
+		buf, cper_event->event_data_length, cper_event->event_data,
+		cper_event_length - sizeof(*cper_event));
+	if (rc) {
+		return rc;
+	}
 
 	return pldm_msgbuf_destroy_consumed(buf);
 }
diff --git a/src/msgbuf.h b/src/msgbuf.h
index b4fd677..c3498bb 100644
--- a/src/msgbuf.h
+++ b/src/msgbuf.h
@@ -722,14 +722,18 @@
 		int32_t *: pldm__msgbuf_extract_int32,                         \
 		real32_t *: pldm__msgbuf_extract_real32)(ctx, dst)
 
+/**
+ * @ref pldm_msgbuf_extract_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
-pldm__msgbuf_extract_array_void(struct pldm_msgbuf *ctx, void *dst,
-				size_t count)
+pldm__msgbuf_extract_array_void(struct pldm_msgbuf *ctx, size_t count,
+				void *dst, size_t dst_count)
 {
 	assert(ctx);
 
-	if (!ctx->cursor || !dst) {
+	if (!ctx->cursor || !dst || count > dst_count) {
 		return pldm_msgbuf_status(ctx, EINVAL);
 	}
 
@@ -758,23 +762,46 @@
 	return 0;
 }
 
+/**
+ * @ref pldm_msgbuf_extract_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
-pldm_msgbuf_extract_array_char(struct pldm_msgbuf *ctx, char *dst, size_t count)
+pldm_msgbuf_extract_array_char(struct pldm_msgbuf *ctx, size_t count, char *dst,
+			       size_t dst_count)
 {
-	return pldm__msgbuf_extract_array_void(ctx, dst, count);
+	return pldm__msgbuf_extract_array_void(ctx, count, dst, dst_count);
 }
 
+/**
+ * @ref pldm_msgbuf_extract_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
-pldm_msgbuf_extract_array_uint8(struct pldm_msgbuf *ctx, uint8_t *dst,
-				size_t count)
+pldm_msgbuf_extract_array_uint8(struct pldm_msgbuf *ctx, size_t count,
+				uint8_t *dst, size_t dst_count)
 {
-	return pldm__msgbuf_extract_array_void(ctx, dst, count);
+	return pldm__msgbuf_extract_array_void(ctx, count, dst, dst_count);
 }
 
-#define pldm_msgbuf_extract_array(ctx, dst, count)                             \
+/**
+ * Extract an array of data from the msgbuf instance
+ *
+ * @param ctx - The msgbuf instance from which to extract an array of data
+ * @param count - The number of array elements to extract
+ * @param dst - The array object into which elements from @p ctx should be
+                extracted
+ * @param dst_count - The maximum number of elements to place into @p dst
+ *
+ * Note that both @p count and @p dst_count can only be counted by `sizeof` for
+ * arrays where `sizeof(*dst) == 1` holds. Specifically, they count the number
+ * of array elements and _not_ the object size of the array.
+ */
+#define pldm_msgbuf_extract_array(ctx, count, dst, dst_count)                  \
 	_Generic((*(dst)),                                                     \
 		uint8_t: pldm_msgbuf_extract_array_uint8,                      \
-		char: pldm_msgbuf_extract_array_char)(ctx, dst, count)
+		char: pldm_msgbuf_extract_array_char)(ctx, count, dst,         \
+						      dst_count)
 
 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_insert_uint32(struct pldm_msgbuf *ctx,
 						       const uint32_t src)
@@ -967,14 +994,18 @@
 		uint32_t: pldm_msgbuf_insert_uint32,                           \
 		int32_t: pldm_msgbuf_insert_int32)(dst, src)
 
+/**
+ * @ref pldm_msgbuf_insert_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
-pldm__msgbuf_insert_array_void(struct pldm_msgbuf *ctx, const void *src,
-			       size_t count)
+pldm__msgbuf_insert_array_void(struct pldm_msgbuf *ctx, size_t count,
+			       const void *src, size_t src_count)
 {
 	assert(ctx);
 
-	if (!ctx->cursor || !src) {
+	if (!ctx->cursor || !src || count > src_count) {
 		return pldm_msgbuf_status(ctx, EINVAL);
 	}
 
@@ -1003,24 +1034,47 @@
 	return 0;
 }
 
+/**
+ * @ref pldm_msgbuf_insert_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
-pldm_msgbuf_insert_array_char(struct pldm_msgbuf *ctx, const char *src,
-			      size_t count)
+pldm_msgbuf_insert_array_char(struct pldm_msgbuf *ctx, size_t count,
+			      const char *src, size_t src_count)
 {
-	return pldm__msgbuf_insert_array_void(ctx, src, count);
+	return pldm__msgbuf_insert_array_void(ctx, count, src, src_count);
 }
 
+/**
+ * @ref pldm_msgbuf_insert_array
+ */
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
-pldm_msgbuf_insert_array_uint8(struct pldm_msgbuf *ctx, const uint8_t *src,
-			       size_t count)
+pldm_msgbuf_insert_array_uint8(struct pldm_msgbuf *ctx, size_t count,
+			       const uint8_t *src, size_t src_count)
 {
-	return pldm__msgbuf_insert_array_void(ctx, src, count);
+	return pldm__msgbuf_insert_array_void(ctx, count, src, src_count);
 }
 
-#define pldm_msgbuf_insert_array(dst, src, count)                              \
+/**
+ * Insert an array of data into the msgbuf instance
+ *
+ * @param ctx - The msgbuf instance into which the array of data should be
+ *              inserted
+ * @param count - The number of array elements to insert
+ * @param src - The array object from which elements should be inserted into
+                @p ctx
+ * @param src_count - The maximum number of elements to insert from @p src
+ *
+ * Note that both @p count and @p src_count can only be counted by `sizeof` for
+ * arrays where `sizeof(*dst) == 1` holds. Specifically, they count the number
+ * of array elements and _not_ the object size of the array.
+ */
+#define pldm_msgbuf_insert_array(dst, count, src, src_count)                   \
 	_Generic((*(src)),                                                     \
 		uint8_t: pldm_msgbuf_insert_array_uint8,                       \
-		char: pldm_msgbuf_insert_array_char)(dst, src, count)
+		char: pldm_msgbuf_insert_array_char)(dst, count, src,          \
+						     src_count)
 
 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_required(struct pldm_msgbuf *ctx,
 						       size_t required,
@@ -1271,6 +1325,7 @@
 	return 0;
 }
 
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
 pldm_msgbuf_copy_string_ascii(struct pldm_msgbuf *dst, struct pldm_msgbuf *src)
 {
@@ -1283,9 +1338,10 @@
 		return rc;
 	}
 
-	return pldm__msgbuf_insert_array_void(dst, ascii, len);
+	return pldm__msgbuf_insert_array_void(dst, len, ascii, len);
 }
 
+LIBPLDM_CC_WARN_UNUSED_RESULT
 LIBPLDM_CC_ALWAYS_INLINE int
 pldm_msgbuf_copy_string_utf16(struct pldm_msgbuf *dst, struct pldm_msgbuf *src)
 {
@@ -1298,7 +1354,7 @@
 		return rc;
 	}
 
-	return pldm__msgbuf_insert_array_void(dst, utf16, len);
+	return pldm__msgbuf_insert_array_void(dst, len, utf16, len);
 }
 
 #ifdef __cplusplus
diff --git a/src/oem/meta/file_io.c b/src/oem/meta/file_io.c
index 073c446..9df6263 100644
--- a/src/oem/meta/file_io.c
+++ b/src/oem/meta/file_io.c
@@ -13,22 +13,29 @@
 {
 	struct pldm_msgbuf _buf;
 	struct pldm_msgbuf *buf = &_buf;
+	int rc;
 
 	if (msg == NULL || file_handle == NULL || length == NULL ||
 	    data == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
 	}
 
-	int rc = pldm_msgbuf_init_cc(
-		buf, PLDM_OEM_META_DECODE_WRITE_FILE_IO_MIN_SIZE, msg->payload,
-		payload_length);
+	rc = pldm_msgbuf_init_cc(buf,
+				 PLDM_OEM_META_DECODE_WRITE_FILE_IO_MIN_SIZE,
+				 msg->payload, payload_length);
 	if (rc) {
 		return rc;
 	}
 
 	pldm_msgbuf_extract_p(buf, file_handle);
 	pldm_msgbuf_extract_p(buf, length);
-	pldm_msgbuf_extract_array_uint8(buf, data, *length);
+
+	/* NOTE: Memory safety failure */
+	rc = pldm_msgbuf_extract_array_uint8(buf, (size_t)(*length), data,
+					     UINT32_MAX);
+	if (rc) {
+		return rc;
+	}
 
 	return pldm_msgbuf_destroy_consumed(buf);
 }
diff --git a/tests/dsp/firmware_update.cpp b/tests/dsp/firmware_update.cpp
index 8e96708..e21daf0 100644
--- a/tests/dsp/firmware_update.cpp
+++ b/tests/dsp/firmware_update.cpp
@@ -1940,17 +1940,24 @@
     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
     pldm_msgbuf_insert_uint8(buf, activeCompVerStrLen);
-    pldm_msgbuf_insert_array_char(buf, release_date, sizeof(release_date));
+    rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
+                                       sizeof(release_date));
+    ASSERT_EQ(rc, 0);
     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
     pldm_msgbuf_insert_uint8(buf, pendingCompVerStrLen);
-    pldm_msgbuf_insert_array_char(buf, release_date, sizeof(release_date));
+    rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
+                                       sizeof(release_date));
+    ASSERT_EQ(rc, 0);
     pldm_msgbuf_insert_uint16(buf, compActivationMethods);
     pldm_msgbuf_insert_uint32(buf, capabilitiesDuringUpdate);
-    pldm_msgbuf_insert_array_char(buf, activeCompVerStr,
-                                  sizeof(activeCompVerStr));
-    pldm_msgbuf_insert_array_char(buf, pendingCompVerStr,
-                                  sizeof(pendingCompVerStr));
+    rc = pldm_msgbuf_insert_array_char(
+        buf, activeCompVerStrLen, activeCompVerStr, sizeof(activeCompVerStr));
+    ASSERT_EQ(rc, 0);
+    rc = pldm_msgbuf_insert_array_char(buf, pendingCompVerStrLen,
+                                       pendingCompVerStr,
+                                       sizeof(pendingCompVerStr));
+    ASSERT_EQ(rc, 0);
 
     variable_field rawData = {.ptr = responseMsg.data(),
                               .length = responseMsg.size()};
diff --git a/tests/dsp/platform.cpp b/tests/dsp/platform.cpp
index b121399..980cf5f 100644
--- a/tests/dsp/platform.cpp
+++ b/tests/dsp/platform.cpp
@@ -388,6 +388,81 @@
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
 }
 
+#ifdef LIBPLDM_API_TESTING
+TEST(GetPDR, testGoodDecodeResponseSafe)
+{
+    static const char recordData[] = "123456789";
+
+    alignas(pldm_msg) unsigned char data[sizeof(pldm_msg_hdr) +
+                                         PLDM_GET_PDR_MIN_RESP_BYTES +
+                                         sizeof(recordData) - 1 + 1];
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    int rc;
+
+    pldm_msg* msg = new (data) pldm_msg;
+
+    rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
+                                sizeof(data) - sizeof(msg->hdr));
+    ASSERT_EQ(rc, 0);
+
+    pldm_msgbuf_insert_uint8(buf, PLDM_SUCCESS);
+    pldm_msgbuf_insert_uint32(buf, 0);
+    pldm_msgbuf_insert_uint32(buf, 0);
+    pldm_msgbuf_insert_uint8(buf, PLDM_END);
+    pldm_msgbuf_insert_uint16(buf, sizeof(recordData) - 1);
+    rc = pldm_msgbuf_insert_array_char(buf, sizeof(recordData) - 1, recordData,
+                                       sizeof(recordData) - 1);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, 96);
+    ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
+
+    alignas(pldm_get_pdr_resp) unsigned char
+        resp_data[sizeof(pldm_get_pdr_resp) + sizeof(recordData) - 1];
+    pldm_get_pdr_resp* resp = new (resp_data) pldm_get_pdr_resp;
+    uint8_t crc;
+    rc = decode_get_pdr_resp_safe(msg, sizeof(data) - sizeof(msg->hdr), resp,
+                                  sizeof(resp_data) - sizeof(*resp), &crc);
+    ASSERT_EQ(rc, 0);
+    EXPECT_EQ(resp->completion_code, PLDM_SUCCESS);
+    EXPECT_EQ(resp->next_record_handle, 0);
+    EXPECT_EQ(resp->next_data_transfer_handle, 0);
+    EXPECT_EQ(resp->transfer_flag, PLDM_END);
+    ASSERT_EQ(resp->response_count, sizeof(recordData) - 1);
+    EXPECT_EQ(crc, 96);
+    EXPECT_EQ(0, memcmp(recordData, resp->record_data, resp->response_count));
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetPDR, testBadDecodeResponseSafeTrivial)
+{
+    pldm_get_pdr_resp resp;
+    uint8_t crc;
+    int rc;
+
+    rc = decode_get_pdr_resp_safe(nullptr, PLDM_GET_PDR_MIN_RESP_BYTES, &resp,
+                                  sizeof(resp), &crc);
+    EXPECT_EQ(rc, -EINVAL);
+
+    alignas(pldm_msg) unsigned char
+        msg_data[sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES];
+    pldm_msg* msg = new (msg_data) pldm_msg;
+    rc = decode_get_pdr_resp_safe(msg, PLDM_GET_PDR_MIN_RESP_BYTES, nullptr,
+                                  sizeof(resp), &crc);
+    EXPECT_EQ(rc, -EINVAL);
+
+    rc = decode_get_pdr_resp_safe(msg, PLDM_GET_PDR_MIN_RESP_BYTES, &resp,
+                                  sizeof(resp), nullptr);
+    EXPECT_EQ(rc, -EINVAL);
+
+    msg->payload[0] = PLDM_ERROR_INVALID_DATA;
+    rc = decode_get_pdr_resp_safe(msg, 1, &resp, sizeof(resp), &crc);
+    EXPECT_EQ(rc, 0);
+    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
 TEST(GetPDRRepositoryInfo, testGoodEncodeResponse)
 {
     uint8_t completionCode = 0;
@@ -550,6 +625,82 @@
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 }
 
+#ifdef LIBPLDM_API_TESTING
+TEST(GetPDRRepositoryInfo, testGoodDecodeResponseSafe)
+{
+    alignas(pldm_msg) unsigned char
+        data[sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES];
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    struct pldm_msgbuf _buf;
+    struct pldm_msgbuf* buf = &_buf;
+    int rc;
+
+    pldm_msg* msg = new (data) pldm_msg;
+
+    rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
+                                msg->payload, sizeof(data) - sizeof(msg->hdr));
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, PLDM_SUCCESS);
+    pldm_msgbuf_insert_uint8(buf, PLDM_AVAILABLE);
+    rc = pldm_msgbuf_insert_array_uint8(buf, PLDM_TIMESTAMP104_SIZE, updateTime,
+                                        sizeof(updateTime));
+    ASSERT_EQ(rc, 0);
+    rc = pldm_msgbuf_insert_array_uint8(buf, PLDM_TIMESTAMP104_SIZE,
+                                        oemUpdateTime, sizeof(oemUpdateTime));
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint32(buf, 100);
+    pldm_msgbuf_insert_uint32(buf, 100);
+    pldm_msgbuf_insert_uint32(buf, UINT32_MAX);
+    pldm_msgbuf_insert_uint8(buf, PLDM_NO_TIMEOUT);
+    ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
+
+    struct pldm_pdr_repository_info_resp resp;
+    rc = decode_get_pdr_repository_info_resp_safe(
+        msg, sizeof(data) - sizeof(msg->hdr), &resp);
+
+    EXPECT_EQ(rc, 0);
+    EXPECT_EQ(PLDM_SUCCESS, resp.completion_code);
+    EXPECT_EQ(PLDM_AVAILABLE, resp.repository_state);
+    EXPECT_EQ(0,
+              memcmp(updateTime, resp.update_time, sizeof(resp.update_time)));
+    EXPECT_EQ(0, memcmp(oemUpdateTime, resp.oem_update_time,
+                        sizeof(resp.oem_update_time)));
+    EXPECT_EQ(100, resp.record_count);
+    EXPECT_EQ(100, resp.repository_size);
+    EXPECT_EQ(UINT32_MAX, resp.largest_record_size);
+    EXPECT_EQ(PLDM_NO_TIMEOUT, resp.data_transfer_handle_timeout);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetPDRRepositoryInfo, testBadDecodeResponseSafeTrivial)
+{
+    struct pldm_pdr_repository_info_resp resp;
+    int rc;
+
+    rc = decode_get_pdr_repository_info_resp_safe(
+        nullptr, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, &resp);
+    EXPECT_EQ(rc, -EINVAL);
+
+    alignas(pldm_msg) unsigned char
+        msg_data[sizeof(pldm_msg) - 1 +
+                 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES];
+    pldm_msg* msg = new (msg_data) pldm_msg;
+    rc = decode_get_pdr_repository_info_resp_safe(msg, 0, &resp);
+    EXPECT_EQ(rc, -EOVERFLOW);
+
+    rc = decode_get_pdr_repository_info_resp_safe(
+        msg, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, nullptr);
+    EXPECT_EQ(rc, -EINVAL);
+
+    msg->payload[0] = PLDM_ERROR_INVALID_DATA;
+    rc = decode_get_pdr_repository_info_resp_safe(msg, 1, &resp);
+    EXPECT_EQ(rc, 0);
+    EXPECT_EQ(resp.completion_code, PLDM_ERROR_INVALID_DATA);
+}
+#endif
+
 TEST(SetNumericEffecterValue, testGoodDecodeRequest)
 {
     std::array<uint8_t,
@@ -1659,7 +1810,9 @@
     pldm_msgbuf_extract_uint8(buf, &retTransferFlag);
     pldm_msgbuf_extract_uint8(buf, &retEventClass);
     pldm_msgbuf_extract_uint32(buf, &retEventDataSize);
-    pldm_msgbuf_extract_array_uint8(buf, retEventData, retEventDataSize);
+    rc = pldm_msgbuf_extract_array_uint8(buf, retEventDataSize, retEventData,
+                                         sizeof(retEventData));
+    ASSERT_EQ(rc, 0);
     pldm_msgbuf_extract_uint32(buf, &retEventDataIntegrityChecksum);
 
     EXPECT_EQ(rc, PLDM_SUCCESS);
@@ -5267,7 +5420,7 @@
     rc = decode_pldm_platform_cper_event(
         reinterpret_cast<uint8_t*>(eventData.data()), eventData.size() - 1,
         cperEvent, cperEventSize);
-    EXPECT_EQ(rc, -EBADMSG);
+    EXPECT_EQ(rc, -EOVERFLOW);
 #else
     EXPECT_DEATH(decode_pldm_platform_cper_event(
                      reinterpret_cast<uint8_t*>(eventData.data()),
diff --git a/tests/msgbuf.cpp b/tests/msgbuf.cpp
index c84acce..e7f9e62 100644
--- a/tests/msgbuf.cpp
+++ b/tests/msgbuf.cpp
@@ -413,7 +413,7 @@
     uint8_t arr[1];
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, 0), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, 0), PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, 0, arr, 0), PLDM_SUCCESS);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
 }
 
@@ -425,8 +425,9 @@
     uint8_t arr[1];
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_extract_array_uint8(ctx, sizeof(arr), arr, sizeof(arr)),
+        PLDM_SUCCESS);
     EXPECT_EQ(arr[0], 0);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
 }
@@ -439,8 +440,9 @@
     uint8_t arr[2];
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_NE(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
-              PLDM_SUCCESS);
+    EXPECT_NE(
+        pldm_msgbuf_extract_array_uint8(ctx, sizeof(arr), arr, sizeof(arr)),
+        PLDM_SUCCESS);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
 }
 
@@ -453,7 +455,7 @@
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, 0), PLDM_SUCCESS);
     ctx->remaining = INTMAX_MIN;
-    EXPECT_NE(pldm_msgbuf_extract_array_uint8(ctx, arr, 1), PLDM_SUCCESS);
+    EXPECT_NE(pldm_msgbuf_extract_array_uint8(ctx, 1, arr, 1), PLDM_SUCCESS);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
 }
 
@@ -465,7 +467,7 @@
     char arr[1] = {'1'};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, 0), 0);
-    EXPECT_EQ(pldm_msgbuf_extract_array_char(ctx, arr, 0), 0);
+    EXPECT_EQ(pldm_msgbuf_extract_array_char(ctx, 0, arr, 0), 0);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), 0);
 }
 
@@ -477,7 +479,8 @@
     char arr[1] = {'1'};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
-    EXPECT_EQ(pldm_msgbuf_extract_array_char(ctx, arr, sizeof(arr)), 0);
+    EXPECT_EQ(
+        pldm_msgbuf_extract_array_char(ctx, sizeof(arr), arr, sizeof(arr)), 0);
     EXPECT_EQ(arr[0], '\0');
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), 0);
 }
@@ -490,7 +493,8 @@
     char arr[2] = {'1', '2'};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
-    EXPECT_NE(pldm_msgbuf_extract_array_char(ctx, arr, sizeof(arr)), 0);
+    EXPECT_NE(
+        pldm_msgbuf_extract_array_char(ctx, sizeof(arr), arr, sizeof(arr)), 0);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), -EOVERFLOW);
 }
 
@@ -503,7 +507,7 @@
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, 0), 0);
     ctx->remaining = INTMAX_MIN;
-    EXPECT_NE(pldm_msgbuf_extract_array_char(ctx, arr, 1), 0);
+    EXPECT_NE(pldm_msgbuf_extract_array_char(ctx, 1, arr, 1), 0);
     ASSERT_EQ(pldm_msgbuf_destroy(ctx), -EOVERFLOW);
 }
 
@@ -773,17 +777,18 @@
     uint8_t retBuff[6] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, src, sizeof(src)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)),
+        PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctxExtract, 0, buf, sizeof(buf)),
               PLDM_SUCCESS);
-    EXPECT_EQ(
-        pldm_msgbuf_extract_array_uint8(ctxExtract, retBuff, sizeof(retBuff)),
-        PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctxExtract, sizeof(retBuff),
+                                              retBuff, sizeof(retBuff)),
+              PLDM_SUCCESS);
 
     EXPECT_EQ(memcmp(src, retBuff, sizeof(retBuff)), 0);
     EXPECT_EQ(pldm_msgbuf_destroy(ctxExtract), PLDM_SUCCESS);
@@ -798,8 +803,9 @@
     uint8_t buf[6] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, NULL, sizeof(src)),
-              PLDM_ERROR_INVALID_DATA);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), NULL, sizeof(src)),
+        PLDM_ERROR_INVALID_DATA);
     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
 }
 
@@ -813,8 +819,9 @@
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, 0), PLDM_SUCCESS);
     ctx->remaining = INTMAX_MIN + sizeof(val) - 1;
-    EXPECT_NE(pldm_msgbuf_insert_array_uint8(ctx, val, sizeof(val)),
-              PLDM_SUCCESS);
+    EXPECT_NE(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(val), val, sizeof(val)),
+        PLDM_SUCCESS);
     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
 }
 
@@ -827,15 +834,16 @@
     char retBuff[6] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
-    EXPECT_EQ(pldm_msgbuf_insert_array_char(ctx, src, sizeof(src)), 0);
+    EXPECT_EQ(pldm_msgbuf_insert_array_char(ctx, sizeof(src), src, sizeof(src)),
+              0);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
-    EXPECT_EQ(
-        pldm_msgbuf_extract_array_char(ctxExtract, retBuff, sizeof(retBuff)),
-        0);
+    EXPECT_EQ(pldm_msgbuf_extract_array_char(ctxExtract, sizeof(retBuff),
+                                             retBuff, sizeof(retBuff)),
+              0);
 
     EXPECT_EQ(memcmp(src, retBuff, sizeof(retBuff)), 0);
     EXPECT_EQ(pldm_msgbuf_destroy(ctxExtract), 0);
@@ -850,7 +858,9 @@
     char buf[6] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
-    EXPECT_EQ(pldm_msgbuf_insert_array_char(ctx, NULL, sizeof(src)), -EINVAL);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_char(ctx, sizeof(src), NULL, sizeof(src)),
+        -EINVAL);
     EXPECT_EQ(pldm_msgbuf_destroy(ctx), 0);
 }
 
@@ -863,7 +873,8 @@
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, 0), 0);
     ctx->remaining = INTMAX_MIN + sizeof(val) - 1;
-    EXPECT_NE(pldm_msgbuf_insert_array_char(ctx, val, sizeof(val)), 0);
+    EXPECT_NE(pldm_msgbuf_insert_array_char(ctx, sizeof(val), val, sizeof(val)),
+              0);
     EXPECT_EQ(pldm_msgbuf_destroy(ctx), -EOVERFLOW);
 }
 
@@ -879,8 +890,9 @@
     uint8_t* retBuff = NULL;
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, src, sizeof(src)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)),
+        PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
@@ -907,8 +919,9 @@
     [[maybe_unused]] uint8_t* retBuff = NULL;
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, src, sizeof(src)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)),
+        PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
@@ -1264,8 +1277,9 @@
     uint8_t* retBuff = NULL;
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, src, sizeof(src)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)),
+        PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
@@ -1294,8 +1308,9 @@
     uint8_t* retBuff = NULL;
 
     ASSERT_EQ(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
-    EXPECT_EQ(pldm_msgbuf_insert_array_uint8(ctx, src, sizeof(src)),
-              PLDM_SUCCESS);
+    EXPECT_EQ(
+        pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)),
+        PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
diff --git a/tests/msgbuf_generic.c b/tests/msgbuf_generic.c
index 96b3bb5..32b9ed9 100644
--- a/tests/msgbuf_generic.c
+++ b/tests/msgbuf_generic.c
@@ -139,7 +139,7 @@
 
     expect(pldm_msgbuf_init_cc(ctx, sizeof(buf), buf, sizeof(buf)) ==
            PLDM_SUCCESS);
-    expect(pldm_msgbuf_extract_array(ctx, arr, 1) == PLDM_SUCCESS);
+    expect(pldm_msgbuf_extract_array(ctx, 1, arr, 1) == PLDM_SUCCESS);
     expect(arr[0] == 0);
     expect(pldm_msgbuf_destroy(ctx) == PLDM_SUCCESS);
 }
@@ -291,15 +291,16 @@
     uint8_t retBuff[6] = {0};
 
     expect(pldm_msgbuf_init_cc(ctx, 0, buf, sizeof(buf)) == PLDM_SUCCESS);
-    expect(pldm_msgbuf_insert_array(ctx, src, sizeof(src)) == PLDM_SUCCESS);
+    expect(pldm_msgbuf_insert_array(ctx, sizeof(src), src, sizeof(src)) ==
+           PLDM_SUCCESS);
 
     struct pldm_msgbuf _ctxExtract;
     struct pldm_msgbuf* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_cc(ctxExtract, 0, buf, sizeof(buf)) ==
            PLDM_SUCCESS);
-    expect(pldm_msgbuf_extract_array(ctxExtract, retBuff, sizeof(retBuff)) ==
-           PLDM_SUCCESS);
+    expect(pldm_msgbuf_extract_array(ctxExtract, sizeof(retBuff), retBuff,
+                                     sizeof(retBuff)) == PLDM_SUCCESS);
 
     expect(memcmp(src, retBuff, sizeof(retBuff)) == 0);
     expect(pldm_msgbuf_destroy(ctxExtract) == PLDM_SUCCESS);
diff --git a/tests/oem/meta/fileio.cpp b/tests/oem/meta/fileio.cpp
index da38679..1f11fc5 100644
--- a/tests/oem/meta/fileio.cpp
+++ b/tests/oem/meta/fileio.cpp
@@ -17,6 +17,7 @@
     uint8_t fileHandle = 0x00;
     int32_t dataLengthLE = 0x04;
     uint8_t postCode[4] = {0x93, 0xe0, 0x00, 0xea};
+    int rc;
 
     constexpr auto hdrSize = sizeof(pldm_msg_hdr);
 
@@ -28,7 +29,9 @@
 
     pldm_msgbuf_insert_uint8(ctx, fileHandle);
     pldm_msgbuf_insert_int32(ctx, dataLengthLE);
-    pldm_msgbuf_insert_array_uint8(ctx, postCode, sizeof(postCode));
+    rc = pldm_msgbuf_insert_array_uint8(ctx, sizeof(postCode), postCode,
+                                        sizeof(postCode));
+    ASSERT_EQ(rc, PLDM_SUCCESS);
 
     std::array<uint8_t, oemMetaDecodeWriteFileIoReqBytes> retDataField{};
 
@@ -37,11 +40,11 @@
 
     auto request = reinterpret_cast<pldm_msg*>(buf);
 
-    auto rc = decode_oem_meta_file_io_req(request, sizeof(buf) - hdrSize,
-                                          &retfileHandle, &retFileDataCnt,
-                                          retDataField.data());
+    rc = decode_oem_meta_file_io_req(request, sizeof(buf) - hdrSize,
+                                     &retfileHandle, &retFileDataCnt,
+                                     retDataField.data());
 
-    EXPECT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
     EXPECT_EQ(retfileHandle, fileHandle);
     EXPECT_EQ(retFileDataCnt, dataLengthLE);
     EXPECT_EQ(retDataField[0], postCode[0]);