Fix parsing single section CPER error
Single section CPER logs do not contain a Record Header. The check for
a valid header is now performed only if the content includes a Record
Header. Additionally, this update fixes an issue with the size
calculation for single-section logs.
Tested :
$> ./cper-generate --out single-cper.file --single-section firmware
$> ./cper-convert to-json-section single-cper.file
Change-Id: Id7efec20df3e5b53c6f90330e0770c1f682a8d87
Signed-off-by: John Chung <john.chung@arm.com>
diff --git a/cli-app/cper-convert.c b/cli-app/cper-convert.c
index 84ce618..e011ad3 100644
--- a/cli-app/cper-convert.c
+++ b/cli-app/cper-convert.c
@@ -108,7 +108,7 @@
return;
}
- if (!header_valid(fbuff, readsize)) {
+ if (!is_single_section && !header_valid(fbuff, readsize)) {
// Check if it's base64 encoded
int32_t decoded_len = 0;
UINT8 *decoded = base64_decode(fbuff, readsize, &decoded_len);
diff --git a/cper-parse.c b/cper-parse.c
index 27cfd72..b91a54e 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -414,6 +414,7 @@
json_object *section_ir =
definition->ToIR(cper_section_buf, size, &cper_description);
if (section_ir == NULL) {
+ free(cper_description);
return NULL;
}
json_object *result = json_object_new_object();
@@ -527,7 +528,7 @@
json_object_object_add(ir, "sectionDescriptor", section_descriptor_ir);
section_begin = cper_buf + section_descriptor->SectionOffset;
- if (section_begin + section_descriptor->SectionLength >= cper_end) {
+ if (section_begin + section_descriptor->SectionLength > cper_end) {
json_object_put(ir);
//cper_print_log("Invalid CPER file: Invalid section descriptor (section offset + length > size).\n");
return NULL;
diff --git a/tests/ir-tests.c b/tests/ir-tests.c
index f8a6990..ad4ae3b 100644
--- a/tests/ir-tests.c
+++ b/tests/ir-tests.c
@@ -311,6 +311,44 @@
}
}
+//Tests a single randomly generated CPER section of the given type to ensure CPER-JSON IR validity.
+void cper_buf_log_section_ir_test(const char *section_name, int single_section,
+ GEN_VALID_BITS_TEST_TYPE validBitsType)
+{
+ //Generate full CPER record for the given type.
+ char *buf;
+ size_t size;
+ FILE *record = generate_record_memstream(§ion_name, 1, &buf, &size,
+ single_section, validBitsType);
+
+ //Convert.
+ json_object *ir;
+ if (single_section) {
+ ir = cper_buf_single_section_to_ir((UINT8 *)buf, size);
+ } else {
+ ir = cper_buf_to_ir((UINT8 *)buf, size);
+ }
+ fclose(record);
+ free(buf);
+
+ if (!ir) {
+ printf("IR validation test failed (%d) : json object empty \n",
+ single_section);
+ assert(0);
+ }
+
+ //Validate against schema.
+ int valid = schema_validate_from_file(ir, single_section,
+ /*all_valid_bits*/ 1);
+ json_object_put(ir);
+
+ if (valid < 0) {
+ printf("IR validation test failed (single section mode = %d)\n",
+ single_section);
+ assert(0);
+ }
+}
+
int to_hex(const unsigned char *input, size_t size, char **out)
{
*out = (char *)malloc(size * 2);
@@ -393,8 +431,14 @@
//Tests randomly generated CPER sections for IR validity of a given type, in both single section mode and full CPER log mode.
void cper_log_section_dual_ir_test(const char *section_name)
{
+ // Test with file based APIs
cper_log_section_ir_test(section_name, 0, allValidbitsSet);
cper_log_section_ir_test(section_name, 1, allValidbitsSet);
+
+ // Test with buffer based APIs
+ cper_buf_log_section_ir_test(section_name, 0, allValidbitsSet);
+ cper_buf_log_section_ir_test(section_name, 1, allValidbitsSet);
+
//Validate against examples
cper_example_section_ir_test(section_name);
}