platform: pldm_msgbuf for decode_get_pdr_resp()

The rework in this patch is the first use pldm_msgbuf on a message type
with variable-length data. The length of the data is embedded in the
message and is one of the elements that we must extract. As we need to
use the extracted length value we must first ensure that the value has
been successfully extracted. This requires we test against the return
value of `pldm_msgbuf_extract()` and _not_ batch the evaluation of
success like we have elsewhere.

Another side-effect is the rework affects mechanics of the "bad" test.
To accommodate that, the change to `recordDataLength` sets the message
up such that the length of the variable data embedded in the message is
1 byte longer than the supplied buffer into which the data should be
extracted.  This arrangement upholds the test expectation that
decode_get_pdr_resp() returns PLDM_ERROR_INVALID_LENGTH for the provided
message buffer.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I6916d28cdd1e27f180fb52725a836a365299ee9a
diff --git a/src/platform.c b/src/platform.c
index 813fabd..25c18bc 100644
--- a/src/platform.c
+++ b/src/platform.c
@@ -489,53 +489,47 @@
 			uint8_t *record_data, size_t record_data_length,
 			uint8_t *transfer_crc)
 {
+	struct pldm_msgbuf _buf;
+	struct pldm_msgbuf *buf = &_buf;
+	int rc;
+
 	if (msg == NULL || completion_code == NULL ||
 	    next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
 	    transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
 	}
 
-	*completion_code = msg->payload[0];
+	rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
+			      payload_length);
+	if (rc) {
+		return rc;
+	}
+
+	pldm_msgbuf_extract(buf, completion_code);
 	if (PLDM_SUCCESS != *completion_code) {
 		return PLDM_SUCCESS;
 	}
 
-	if (payload_length < PLDM_GET_PDR_MIN_RESP_BYTES) {
-		return PLDM_ERROR_INVALID_LENGTH;
-	}
-
-	struct pldm_get_pdr_resp *response =
-	    (struct pldm_get_pdr_resp *)msg->payload;
-
-	*next_record_hndl = le32toh(response->next_record_handle);
-	*next_data_transfer_hndl = le32toh(response->next_data_transfer_handle);
-	*transfer_flag = response->transfer_flag;
-	*resp_cnt = le16toh(response->response_count);
-
-	if (*transfer_flag != PLDM_END &&
-	    (int)payload_length != PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt) {
-		return PLDM_ERROR_INVALID_LENGTH;
-	}
-
-	if (*transfer_flag == PLDM_END &&
-	    (int)payload_length !=
-		PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt + 1) {
-		return PLDM_ERROR_INVALID_LENGTH;
+	pldm_msgbuf_extract(buf, next_record_hndl);
+	pldm_msgbuf_extract(buf, next_data_transfer_hndl);
+	pldm_msgbuf_extract(buf, transfer_flag);
+	rc = pldm_msgbuf_extract(buf, resp_cnt);
+	if (rc) {
+		return rc;
 	}
 
 	if (*resp_cnt > 0 && record_data != NULL) {
 		if (record_data_length < *resp_cnt) {
 			return PLDM_ERROR_INVALID_LENGTH;
 		}
-		memcpy(record_data, response->record_data, *resp_cnt);
+		pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
 	}
 
 	if (*transfer_flag == PLDM_END) {
-		*transfer_crc =
-		    msg->payload[PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt];
+		pldm_msgbuf_extract(buf, transfer_crc);
 	}
 
-	return PLDM_SUCCESS;
+	return pldm_msgbuf_destroy(buf);
 }
 
 int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
diff --git a/tests/libpldm_platform_test.cpp b/tests/libpldm_platform_test.cpp
index c493e3e..5a5f131 100644
--- a/tests/libpldm_platform_test.cpp
+++ b/tests/libpldm_platform_test.cpp
@@ -351,7 +351,7 @@
     uint8_t transferFlag = PLDM_END;
     constexpr uint16_t respCnt = 9;
     uint8_t transferCRC = 96;
-    size_t recordDataLength = 32;
+    size_t recordDataLength = respCnt - 1;
     std::array<uint8_t, hdrSize + PLDM_GET_PDR_MIN_RESP_BYTES + respCnt +
                             sizeof(transferCRC)>
         responseMsg{};