bios: Verify the fields that need to be encoded

Implement functions to verify the fields that to be
encoded and set error message.

Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I897f72497b36f6c62a577b5c062adf7edbad5607
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index 271d179..2512f5e 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -28,6 +28,12 @@
 
 #define MEMBER_SIZE(type, member) sizeof(((struct type *)0)->member)
 
+static void set_errmsg(const char **errmsg, const char *msg)
+{
+	if (errmsg != NULL)
+		*errmsg = msg;
+}
+
 static uint16_t get_bios_string_handle()
 {
 	static uint16_t handle = 0;
@@ -295,6 +301,42 @@
 		       info->def_length);
 }
 
+#define PLDM_STRING_TYPE_MAX 5
+#define PLDM_STRING_TYPE_VENDOR 0xff
+
+int pldm_bios_table_attr_entry_string_info_check(
+    const struct pldm_bios_table_attr_entry_string_info *info,
+    const char **errmsg)
+{
+	if (info->min_length > info->max_length) {
+		set_errmsg(errmsg, "MinimumStingLength should not be greater "
+				   "than MaximumStringLength");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->min_length == info->max_length &&
+	    info->def_length != info->min_length) {
+		set_errmsg(errmsg, "Wrong DefaultStringLength");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->def_length > info->max_length ||
+	    info->def_length < info->min_length) {
+		set_errmsg(errmsg, "Wrong DefaultStringLength");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->string_type > PLDM_STRING_TYPE_MAX &&
+	    info->string_type != PLDM_STRING_TYPE_VENDOR) {
+		set_errmsg(errmsg, "Wrong StringType");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->def_length != strlen(info->def_string)) {
+		set_errmsg(errmsg, "Length of DefaultString should be equal to "
+				   "DefaultStringLength");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	return PLDM_SUCCESS;
+}
+
 int pldm_bios_table_attr_entry_string_encode_check(
     void *entry, size_t entry_length,
     const struct pldm_bios_table_attr_entry_string_info *info)
@@ -304,11 +346,8 @@
 	size_t length =
 	    pldm_bios_table_attr_entry_string_encode_length(info->def_length);
 	BUFFER_SIZE_EXPECT(entry_length, length);
-	if (info->def_length > info->max_length ||
-	    info->def_length < info->min_length ||
-	    info->min_length > info->max_length)
-		return PLDM_ERROR_INVALID_DATA;
-	if (info->string_type > 5 && info->string_type != 0xFF)
+	if (pldm_bios_table_attr_entry_string_info_check(info, NULL) !=
+	    PLDM_SUCCESS)
 		return PLDM_ERROR_INVALID_DATA;
 	pldm_bios_table_attr_entry_string_encode(entry, entry_length, info);
 	return PLDM_SUCCESS;
@@ -375,6 +414,45 @@
 	attr_fields->default_value = htole64(info->default_value);
 }
 
+int pldm_bios_table_attr_entry_integer_info_check(
+    const struct pldm_bios_table_attr_entry_integer_info *info,
+    const char **errmsg)
+{
+	if (info->lower_bound == info->upper_bound) {
+		if (info->default_value != info->lower_bound) {
+			set_errmsg(errmsg, "Wrong DefaultValue");
+			return PLDM_ERROR_INVALID_DATA;
+		}
+		if (info->scalar_increment != 0) {
+			set_errmsg(errmsg, "Wrong ScalarIncrement");
+			return PLDM_ERROR_INVALID_DATA;
+		}
+		return PLDM_SUCCESS;
+	}
+	if (info->lower_bound > info->upper_bound) {
+		set_errmsg(errmsg,
+			   "LowerBound should not be greater than UpperBound");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->default_value > info->upper_bound ||
+	    info->default_value < info->lower_bound) {
+		set_errmsg(errmsg, "Wrong DefaultValue");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (info->scalar_increment == 0) {
+		set_errmsg(errmsg, "ScalarIncrement should not be zero when "
+				   "lower_bound != upper_bound");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if ((info->default_value - info->lower_bound) %
+		info->scalar_increment !=
+	    0) {
+		set_errmsg(errmsg, "Wrong DefaultValue or ScalarIncrement");
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	return PLDM_SUCCESS;
+}
+
 int pldm_bios_table_attr_entry_integer_encode_check(
     void *entry, size_t entry_length,
     const struct pldm_bios_table_attr_entry_integer_info *info)
@@ -383,12 +461,8 @@
 	POINTER_CHECK(info);
 	size_t length = pldm_bios_table_attr_entry_integer_encode_length();
 	BUFFER_SIZE_EXPECT(entry_length, length);
-	if (info->lower_bound > info->upper_bound ||
-	    info->default_value > info->upper_bound ||
-	    info->default_value < info->lower_bound ||
-	    (info->default_value - info->lower_bound) %
-		    info->scalar_increment !=
-		0)
+	if (pldm_bios_table_attr_entry_integer_info_check(info, NULL) !=
+	    PLDM_SUCCESS)
 		return PLDM_ERROR_INVALID_DATA;
 	pldm_bios_table_attr_entry_integer_encode(entry, entry_length, info);
 	return PLDM_SUCCESS;
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
index 0a4fcd6..bd42690 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -269,6 +269,16 @@
 	const char *def_string; //!< The default string itself
 };
 
+/** @brief Check fields in @ref pldm_bios_table_attr_entry_string_info
+ *  @param[in] info - Pointer to the pldm_bios_table_attr_entry_string_info
+ *  @param[out] errmsg - Pointer to an errmsg stored in the statically allocated
+ * memory
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_info_check(
+    const struct pldm_bios_table_attr_entry_string_info *info,
+    const char **errmsg);
+
 /** @brief Get length that an attribute entry(type: string) will take
  *  @param[in] def_str_len - Length of default string
  *  @return The length that an entry(type: string) will take
@@ -330,6 +340,16 @@
 	uint64_t default_value;    //!< The default value of the integer
 };
 
+/** @brief Check fields in @ref pldm_bios_table_attr_entry_integer_info
+ *  @param[in] info - Pointer to the pldm_bios_table_attr_entry_integer_info
+ *  @param[out] errmsg - Pointer to an errmsg stored in the statically allocated
+ * memory
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_integer_info_check(
+    const struct pldm_bios_table_attr_entry_integer_info *info,
+    const char **errmsg);
+
 /** @brief Get length that an attribute entry(type: integer) will take
  *  @return The length that an entry(type: integer) will take
  */
diff --git a/test/libpldm_bios_table_test.cpp b/test/libpldm_bios_table_test.cpp
index d22f61c..84468d3 100644
--- a/test/libpldm_bios_table_test.cpp
+++ b/test/libpldm_bios_table_test.cpp
@@ -238,6 +238,12 @@
         encodeEntry.data(), encodeEntry.size() - 1, &info);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
     std::swap(info.max_length, info.min_length);
+    const char* errmsg;
+    rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    EXPECT_STREQ(
+        "MinimumStingLength should not be greater than MaximumStringLength",
+        errmsg);
     rc = pldm_bios_table_attr_entry_string_encode_check(
         encodeEntry.data(), encodeEntry.size(), &info);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
@@ -323,6 +329,10 @@
 
     info.lower_bound = 100;
     info.upper_bound = 50;
+    const char* errmsg;
+    rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+    EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg);
     rc = pldm_bios_table_attr_entry_integer_encode_check(
         encodeEntry.data(), encodeEntry.size(), &info);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);