Fix some json schema validation bugs
There were a couple of places where we would add null objects when
they were not allowed. Fix them.
Change-Id: I7c4c12ea1fa2913014e79603995267a9e560e288
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/cper-parse.c b/cper-parse.c
index 2a68fab..ccd863f 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -114,15 +114,19 @@
const unsigned char *section_begin =
cper_buf + section_descriptor->SectionOffset;
-
- json_object_array_add(
- section_descriptors_ir,
- cper_section_descriptor_to_ir(section_descriptor));
+ json_object *section_descriptor_ir =
+ cper_section_descriptor_to_ir(section_descriptor);
+ json_object_array_add(section_descriptors_ir,
+ section_descriptor_ir);
//Read the section itself.
json_object *section_ir = cper_buf_section_to_ir(
section_begin, section_descriptor->SectionLength,
section_descriptor);
+ if (section_ir == NULL) {
+ cper_print_log("Failed to parse section %d\n", i);
+ section_ir = json_object_new_object();
+ }
json_object_array_add(sections_ir, section_ir);
}
@@ -219,16 +223,15 @@
if (header->ValidationBits & 0x2) {
char timestamp_string[TIMESTAMP_LENGTH];
if (timestamp_to_string(timestamp_string, TIMESTAMP_LENGTH,
- &header->TimeStamp) < 0) {
- goto fail;
- }
- json_object_object_add(
- header_ir, "timestamp",
- json_object_new_string(timestamp_string));
+ &header->TimeStamp) >= 0) {
+ json_object_object_add(
+ header_ir, "timestamp",
+ json_object_new_string(timestamp_string));
- json_object_object_add(
- header_ir, "timestampIsPrecise",
- json_object_new_boolean(header->TimeStamp.Flag));
+ json_object_object_add(header_ir, "timestampIsPrecise",
+ json_object_new_boolean(
+ header->TimeStamp.Flag));
+ }
}
//If a platform ID exists according to the validation bits, then add it.
@@ -298,10 +301,6 @@
json_object_object_add(header_ir, "persistenceInfo",
json_object_new_uint64(header->PersistenceInfo));
return header_ir;
-
-fail:
- json_object_put(header_ir);
- return NULL;
}
//Converts the given EFI section descriptor into JSON IR format.
@@ -398,6 +397,9 @@
return NULL;
}
json_object *section_ir = definition->ToIR(cper_section_buf, size);
+ if (section_ir == NULL) {
+ return NULL;
+ }
json_object *result = json_object_new_object();
json_object_object_add(result, definition->ShortName, section_ir);
return result;
@@ -440,12 +442,13 @@
//Parse section to IR based on GUID.
json_object *result = NULL;
-
json_object *section_ir = NULL;
CPER_SECTION_DEFINITION *section =
select_section_by_guid(&descriptor->SectionType);
- if (section != NULL) {
+ if (section == NULL) {
+ cper_print_log("Unknown section type guid\n");
+ } else {
result = read_section(cper_section_buf, size, section);
}
@@ -457,7 +460,8 @@
descriptor->SectionLength,
&encoded_len);
if (encoded == NULL) {
- //cper_print_log("Failed to allocate encode output buffer. \n");
+ cper_print_log(
+ "Failed to allocate encode output buffer. \n");
} else {
section_ir = json_object_new_object();
json_object_object_add(section_ir, "data",
@@ -469,7 +473,9 @@
json_object_object_add(result, "Unknown", section_ir);
}
}
-
+ if (result == NULL) {
+ cper_print_log("RETURNING NULL!! !!\n");
+ }
return result;
}
@@ -511,6 +517,9 @@
//Parse the single section.
json_object *section_ir = cper_buf_section_to_ir(
section, section_descriptor->SectionLength, section_descriptor);
+ if (section_ir == NULL) {
+ cper_print_log("RETURNING NULL2!! !!\n");
+ }
json_object_object_add(ir, "section", section_ir);
return ir;
}
diff --git a/ir-parse.c b/ir-parse.c
index ef588f1..e9c3966 100644
--- a/ir-parse.c
+++ b/ir-parse.c
@@ -174,17 +174,17 @@
json_object *ir = NULL;
//Find the correct section type, and parse.
- int section_converted = 0;
CPER_SECTION_DEFINITION *definition =
select_section_by_guid(&descriptor->SectionType);
- if (definition != NULL) {
+ if (definition == NULL) {
+ cper_print_log("Unknown section type guid\n");
+ } else {
ir = json_object_object_get(section, definition->ShortName);
definition->ToCPER(ir, out);
- section_converted = 1;
}
//If unknown GUID, so read as a base64 unknown section.
- if (!section_converted) {
+ if (ir == NULL) {
ir = json_object_object_get(section, "Unknown");
json_object *encoded = json_object_object_get(ir, "data");
diff --git a/meson.build b/meson.build
index 8c7319a..a946d11 100644
--- a/meson.build
+++ b/meson.build
@@ -14,7 +14,7 @@
add_project_arguments(
'-DLIBCPER_JSON_SPEC="'
- + meson.current_source_dir() + '/specification/json/cper-json.json"',
+ + meson.current_source_dir() + '/specification/json"',
language: ['c', 'cpp'],
)
@@ -53,7 +53,7 @@
edk_sources = files('Cper.c')
-generator_section_sources = files(
+libcper_generate_sources = files(
'generator/sections/gen-section-ampere.c',
'generator/sections/gen-section-arm.c',
'generator/sections/gen-section-ccix-per.c',
@@ -114,16 +114,14 @@
link_with: [libcper_parse],
)
-libcper_generate_sources = [
- 'common-utils.c',
+libcper_generate_sources += files(
'generator/cper-generate.c',
'generator/gen-utils.c',
-]
+)
libcper_generate = library(
'cper-generate',
libcper_generate_sources,
- generator_section_sources,
version: meson.project_version(),
include_directories: libcper_include_dir,
dependencies: [json_c_dep],
diff --git a/sections/cper-section-arm.c b/sections/cper-section-arm.c
index 6961d16..8cce3c4 100644
--- a/sections/cper-section-arm.c
+++ b/sections/cper-section-arm.c
@@ -276,8 +276,11 @@
//Unknown/microarch, will not support.
break;
}
- json_object_object_add(error_info_ir, "errorInformation",
- error_subinfo);
+ if (error_subinfo != NULL) {
+ json_object_object_add(error_info_ir,
+ "errorInformation",
+ error_subinfo);
+ }
}
//Virtual fault address, physical fault address.
diff --git a/sections/cper-section-cxl-protocol.c b/sections/cper-section-cxl-protocol.c
index ebf3648..6ae5325 100644
--- a/sections/cper-section-cxl-protocol.c
+++ b/sections/cper-section-cxl-protocol.c
@@ -42,46 +42,47 @@
"Unknown (Reserved)");
json_object_object_add(section_ir, "agentType", agent_type);
}
-
- //CXL agent address, depending on the agent type.
- json_object *agent_address = json_object_new_object();
- if (cxl_protocol_error->CxlAgentType ==
- CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
- //Address is a CXL1.1 device agent.
- json_object_object_add(
- agent_address, "functionNumber",
- json_object_new_uint64(
- cxl_protocol_error->CxlAgentAddress
- .DeviceAddress.FunctionNumber));
- json_object_object_add(
- agent_address, "deviceNumber",
- json_object_new_uint64(
- cxl_protocol_error->CxlAgentAddress
- .DeviceAddress.DeviceNumber));
- json_object_object_add(
- agent_address, "busNumber",
- json_object_new_uint64(
- cxl_protocol_error->CxlAgentAddress
- .DeviceAddress.BusNumber));
- json_object_object_add(
- agent_address, "segmentNumber",
- json_object_new_uint64(
- cxl_protocol_error->CxlAgentAddress
- .DeviceAddress.SegmentNumber));
- } else if (cxl_protocol_error->CxlAgentType ==
- CXL_PROTOCOL_ERROR_HOST_DOWNSTREAM_PORT_AGENT) {
- //Address is a CXL port RCRB base address.
- json_object_object_add(
- agent_address, "value",
- json_object_new_uint64(
- cxl_protocol_error->CxlAgentAddress
- .PortRcrbBaseAddress));
- }
if (isvalid_prop_to_ir(&ui64Type, 1)) {
- json_object_object_add(section_ir, "cxlAgentAddress",
- agent_address);
- } else {
- json_object_put(agent_address);
+ //CXL agent address, depending on the agent type.
+ json_object *agent_address = NULL;
+ if (cxl_protocol_error->CxlAgentType ==
+ CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
+ agent_address = json_object_new_object();
+ //Address is a CXL1.1 device agent.
+ json_object_object_add(
+ agent_address, "functionNumber",
+ json_object_new_uint64(
+ cxl_protocol_error->CxlAgentAddress
+ .DeviceAddress.FunctionNumber));
+ json_object_object_add(
+ agent_address, "deviceNumber",
+ json_object_new_uint64(
+ cxl_protocol_error->CxlAgentAddress
+ .DeviceAddress.DeviceNumber));
+ json_object_object_add(
+ agent_address, "busNumber",
+ json_object_new_uint64(
+ cxl_protocol_error->CxlAgentAddress
+ .DeviceAddress.BusNumber));
+ json_object_object_add(
+ agent_address, "segmentNumber",
+ json_object_new_uint64(
+ cxl_protocol_error->CxlAgentAddress
+ .DeviceAddress.SegmentNumber));
+ } else if (cxl_protocol_error->CxlAgentType ==
+ CXL_PROTOCOL_ERROR_HOST_DOWNSTREAM_PORT_AGENT) {
+ agent_address = json_object_new_object();
+ //Address is a CXL port RCRB base address.
+ json_object_object_add(
+ agent_address, "value",
+ json_object_new_uint64(
+ cxl_protocol_error->CxlAgentAddress
+ .PortRcrbBaseAddress));
+ }
+ if (agent_address != NULL) {
+ json_object_object_add(section_ir, "cxlAgentAddress",
+ agent_address);
+ }
}
json_object *device_id = json_object_new_object();
diff --git a/sections/cper-section-ia32x64.c b/sections/cper-section-ia32x64.c
index 8f84c11..2206d2a 100644
--- a/sections/cper-section-ia32x64.c
+++ b/sections/cper-section-ia32x64.c
@@ -130,10 +130,14 @@
void *cur_pos = (void *)current_context_info;
json_object *context_info_array = json_object_new_array();
for (int i = 0; i < processor_context_info_num; i++) {
- json_object_array_add(context_info_array,
- cper_ia32x64_processor_context_info_to_ir(
- current_context_info, &cur_pos,
- &remaining_size));
+ json_object *context_info =
+ cper_ia32x64_processor_context_info_to_ir(
+ current_context_info, &cur_pos,
+ &remaining_size);
+ if (context_info == NULL) {
+ context_info = json_object_new_object();
+ }
+ json_object_array_add(context_info_array, context_info);
current_context_info =
(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
@@ -466,11 +470,12 @@
EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
UINT32 *remaining_size)
{
+ json_object *context_info_ir = json_object_new_object();
+
if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
- return NULL;
+ return context_info_ir;
}
*remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
- json_object *context_info_ir = json_object_new_object();
//Register context type.
json_object *context_type = integer_to_readable_pair(
@@ -494,8 +499,7 @@
json_object *register_array = NULL;
if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
- json_object_put(context_info_ir);
- return NULL;
+ return context_info_ir;
}
EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
(EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
@@ -505,8 +509,7 @@
*remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
} else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
- json_object_put(context_info_ir);
- return NULL;
+ return context_info_ir;
}
EFI_CONTEXT_X64_REGISTER_STATE *register_state =
(EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
@@ -518,8 +521,7 @@
//No parseable data, just dump as base64 and shift the head to the next item.
*cur_pos = (void *)(context_info + 1);
if (*remaining_size < context_info->ArraySize) {
- json_object_put(context_info_ir);
- return NULL;
+ return context_info_ir;
}
int32_t encoded_len = 0;
char *encoded = base64_encode((UINT8 *)*cur_pos,
diff --git a/specification/json/sections/cper-ia32x64-processor.json b/specification/json/sections/cper-ia32x64-processor.json
index 371e19f..ac266ed 100644
--- a/specification/json/sections/cper-ia32x64-processor.json
+++ b/specification/json/sections/cper-ia32x64-processor.json
@@ -59,116 +59,51 @@
},
"checkInfo": {
"type": "object",
- "oneOf": [
- {
- "$id": "cper-json-checkinfo0",
+ "additionalProperties": false,
+ "properties": {
+ "transactionType": {
"type": "object",
- "required": [],
- "additionalProperties": false,
- "properties": {
- "transactionType": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "operation": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "level": {
- "type": "integer",
- "minimum": 0
- },
- "processorContextCorrupt": {
- "type": "boolean"
- },
- "uncorrected": {
- "type": "boolean"
- },
- "preciseIP": {
- "type": "boolean"
- },
- "restartableIP": {
- "type": "boolean"
- },
- "overflow": {
- "type": "boolean"
- }
- }
+ "$ref": "./common/cper-json-nvp.json"
},
- {
- "$id": "cper-json-checkinfo1",
+ "operation": {
"type": "object",
- "required": [],
- "additionalProperties": false,
- "properties": {
- "transactionType": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "operation": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "level": {
- "type": "integer",
- "minimum": 0
- },
- "processorContextCorrupt": {
- "type": "boolean"
- },
- "uncorrected": {
- "type": "boolean"
- },
- "preciseIP": {
- "type": "boolean"
- },
- "restartableIP": {
- "type": "boolean"
- },
- "overflow": {
- "type": "boolean"
- },
- "participationType": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "addressSpace": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "timedOut": {
- "type": "boolean"
- }
- }
+ "$ref": "./common/cper-json-nvp.json"
},
- {
- "$id": "cper-json-checkinfo2",
+ "level": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "processorContextCorrupt": {
+ "type": "boolean"
+ },
+ "uncorrected": {
+ "type": "boolean"
+ },
+ "preciseIP": {
+ "type": "boolean"
+ },
+ "restartableIP": {
+ "type": "boolean"
+ },
+ "overflow": {
+ "type": "boolean"
+ },
+ "participationType": {
"type": "object",
- "required": [],
- "additionalProperties": false,
- "properties": {
- "errorType": {
- "type": "object",
- "$ref": "./common/cper-json-nvp.json"
- },
- "processorContextCorrupt": {
- "type": "boolean"
- },
- "uncorrected": {
- "type": "boolean"
- },
- "preciseIP": {
- "type": "boolean"
- },
- "restartableIP": {
- "type": "boolean"
- },
- "overflow": {
- "type": "boolean"
- }
- }
+ "$ref": "./common/cper-json-nvp.json"
+ },
+ "addressSpace": {
+ "type": "object",
+ "$ref": "./common/cper-json-nvp.json"
+ },
+ "timedOut": {
+ "type": "boolean"
+ },
+ "errorType": {
+ "type": "object",
+ "$ref": "./common/cper-json-nvp.json"
}
- ]
+ }
},
"targetAddressID": {
"type": "integer"
@@ -246,31 +181,81 @@
],
"additionalProperties": false,
"properties": {
- "eax": { "type": "integer" },
- "ebx": { "type": "integer" },
- "ecx": { "type": "integer" },
- "edx": { "type": "integer" },
- "esi": { "type": "integer" },
- "edi": { "type": "integer" },
- "ebp": { "type": "integer" },
- "esp": { "type": "integer" },
- "cs": { "type": "integer" },
- "ds": { "type": "integer" },
- "ss": { "type": "integer" },
- "es": { "type": "integer" },
- "fs": { "type": "integer" },
- "gs": { "type": "integer" },
- "eflags": { "type": "integer" },
- "eip": { "type": "integer" },
- "cr0": { "type": "integer" },
- "cr1": { "type": "integer" },
- "cr2": { "type": "integer" },
- "cr3": { "type": "integer" },
- "cr4": { "type": "integer" },
- "gdtr": { "type": "integer" },
- "idtr": { "type": "integer" },
- "ldtr": { "type": "integer" },
- "tr": { "type": "integer" }
+ "eax": {
+ "type": "integer"
+ },
+ "ebx": {
+ "type": "integer"
+ },
+ "ecx": {
+ "type": "integer"
+ },
+ "edx": {
+ "type": "integer"
+ },
+ "esi": {
+ "type": "integer"
+ },
+ "edi": {
+ "type": "integer"
+ },
+ "ebp": {
+ "type": "integer"
+ },
+ "esp": {
+ "type": "integer"
+ },
+ "cs": {
+ "type": "integer"
+ },
+ "ds": {
+ "type": "integer"
+ },
+ "ss": {
+ "type": "integer"
+ },
+ "es": {
+ "type": "integer"
+ },
+ "fs": {
+ "type": "integer"
+ },
+ "gs": {
+ "type": "integer"
+ },
+ "eflags": {
+ "type": "integer"
+ },
+ "eip": {
+ "type": "integer"
+ },
+ "cr0": {
+ "type": "integer"
+ },
+ "cr1": {
+ "type": "integer"
+ },
+ "cr2": {
+ "type": "integer"
+ },
+ "cr3": {
+ "type": "integer"
+ },
+ "cr4": {
+ "type": "integer"
+ },
+ "gdtr": {
+ "type": "integer"
+ },
+ "idtr": {
+ "type": "integer"
+ },
+ "ldtr": {
+ "type": "integer"
+ },
+ "tr": {
+ "type": "integer"
+ }
}
},
{
@@ -315,42 +300,114 @@
],
"additionalProperties": false,
"properties": {
- "rax": { "type": "integer" },
- "rbx": { "type": "integer" },
- "rcx": { "type": "integer" },
- "rdx": { "type": "integer" },
- "rsi": { "type": "integer" },
- "rdi": { "type": "integer" },
- "rbp": { "type": "integer" },
- "rsp": { "type": "integer" },
- "r8": { "type": "integer" },
- "r9": { "type": "integer" },
- "r10": { "type": "integer" },
- "r11": { "type": "integer" },
- "r12": { "type": "integer" },
- "r13": { "type": "integer" },
- "r14": { "type": "integer" },
- "r15": { "type": "integer" },
- "cs": { "type": "integer" },
- "ds": { "type": "integer" },
- "ss": { "type": "integer" },
- "es": { "type": "integer" },
- "fs": { "type": "integer" },
- "gs": { "type": "integer" },
- "rflags": { "type": "integer" },
- "eip": { "type": "integer" },
- "cr0": { "type": "integer" },
- "cr1": { "type": "integer" },
- "cr2": { "type": "integer" },
- "cr3": { "type": "integer" },
- "cr4": { "type": "integer" },
- "cr8": { "type": "integer" },
- "gdtr_0": { "type": "integer" },
- "gdtr_1": { "type": "integer" },
- "idtr_0": { "type": "integer" },
- "idtr_1": { "type": "integer" },
- "ldtr": { "type": "integer" },
- "tr": { "type": "integer" }
+ "rax": {
+ "type": "integer"
+ },
+ "rbx": {
+ "type": "integer"
+ },
+ "rcx": {
+ "type": "integer"
+ },
+ "rdx": {
+ "type": "integer"
+ },
+ "rsi": {
+ "type": "integer"
+ },
+ "rdi": {
+ "type": "integer"
+ },
+ "rbp": {
+ "type": "integer"
+ },
+ "rsp": {
+ "type": "integer"
+ },
+ "r8": {
+ "type": "integer"
+ },
+ "r9": {
+ "type": "integer"
+ },
+ "r10": {
+ "type": "integer"
+ },
+ "r11": {
+ "type": "integer"
+ },
+ "r12": {
+ "type": "integer"
+ },
+ "r13": {
+ "type": "integer"
+ },
+ "r14": {
+ "type": "integer"
+ },
+ "r15": {
+ "type": "integer"
+ },
+ "cs": {
+ "type": "integer"
+ },
+ "ds": {
+ "type": "integer"
+ },
+ "ss": {
+ "type": "integer"
+ },
+ "es": {
+ "type": "integer"
+ },
+ "fs": {
+ "type": "integer"
+ },
+ "gs": {
+ "type": "integer"
+ },
+ "rflags": {
+ "type": "integer"
+ },
+ "eip": {
+ "type": "integer"
+ },
+ "cr0": {
+ "type": "integer"
+ },
+ "cr1": {
+ "type": "integer"
+ },
+ "cr2": {
+ "type": "integer"
+ },
+ "cr3": {
+ "type": "integer"
+ },
+ "cr4": {
+ "type": "integer"
+ },
+ "cr8": {
+ "type": "integer"
+ },
+ "gdtr_0": {
+ "type": "integer"
+ },
+ "gdtr_1": {
+ "type": "integer"
+ },
+ "idtr_0": {
+ "type": "integer"
+ },
+ "idtr_1": {
+ "type": "integer"
+ },
+ "ldtr": {
+ "type": "integer"
+ },
+ "tr": {
+ "type": "integer"
+ }
}
},
{
diff --git a/tests/fuzz_cper_buf_to_ir.cpp b/tests/fuzz_cper_buf_to_ir.cpp
index 586c2ba..4baef7b 100644
--- a/tests/fuzz_cper_buf_to_ir.cpp
+++ b/tests/fuzz_cper_buf_to_ir.cpp
@@ -1,11 +1,28 @@
#include "libcper/cper-parse.h"
+#include "test-utils.hpp"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
json_object *ir = cper_buf_to_ir(data, size);
- if (ir != NULL) {
- json_object_put(ir);
+ if (ir == NULL) {
+ return 0;
}
+ char *str = strdup(json_object_to_json_string(ir));
+
+ nlohmann::json jsonData = nlohmann::json::parse(str, nullptr, false);
+ free(str);
+ assert(jsonData.is_discarded() == false);
+ std::string error_message;
+ static std::unique_ptr<valijson::Schema> schema =
+ load_schema(AddRequiredProps::NO, 0);
+
+ int valid = schema_validate_from_file(*schema, jsonData, error_message);
+ if (!valid) {
+ std::cout << "JSON: " << jsonData.dump(4) << std::endl;
+ std::cout << "Error: " << error_message << std::endl;
+ }
+ assert(valid);
+ json_object_put(ir);
return 0;
}
diff --git a/tests/ir-tests.cpp b/tests/ir-tests.cpp
index 97dad1b..d255353 100644
--- a/tests/ir-tests.cpp
+++ b/tests/ir-tests.cpp
@@ -194,13 +194,14 @@
//Validate against schema.
std::string error_message;
-
- int valid = schema_validate_from_file(LIBCPER_JSON_SPEC, jsonData,
- error_message);
+ std::unique_ptr<valijson::Schema> schema =
+ load_schema(AddRequiredProps::YES, single_section);
+ int valid = schema_validate_from_file(*schema, jsonData, error_message);
json_object_put(ir);
ASSERT_TRUE(valid)
<< "IR validation test failed (single section mode = "
- << single_section << ") with message: " << error_message;
+ << single_section << ") with message: " << error_message
+ << jsonData.dump(4) << "\n";
}
std::string to_hex(char *input, size_t size)
diff --git a/tests/meson.build b/tests/meson.build
index e86f26b..f65dc41 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -38,13 +38,14 @@
valijson_dep = valijson_proj.get_variable('valijson_dep')
endif
-sources = ['ir-tests.cpp', 'test-utils.cpp', 'base64_test.cpp']
+test_sources = ['test-utils.cpp', 'base64_test.cpp']
test_include_dirs = ['.', '../include']
cper_tests = executable(
'cper-tests',
- sources,
+ 'ir-tests.cpp',
+ test_sources,
implicit_include_directories: false,
include_directories: include_directories(test_include_dirs),
cpp_args: '-fpermissive',
@@ -74,7 +75,7 @@
foreach fuzzer_test : ['fuzz_cper_buf_to_ir']
fuzz_exe = executable(
fuzzer_test,
- [fuzzer_test + '.cpp'] + libcper_parse_sources + edk_sources,
+ [fuzzer_test + '.cpp'] + libcper_parse_sources + edk_sources + test_sources + libcper_generate_sources,
implicit_include_directories: false,
include_directories: include_directories(test_include_dirs),
cpp_args: fuzz_args,
diff --git a/tests/test-utils.cpp b/tests/test-utils.cpp
index 88f9d7d..b38b36c 100644
--- a/tests/test-utils.cpp
+++ b/tests/test-utils.cpp
@@ -28,6 +28,11 @@
{ "faultReason", "description" } },
{ "./sections/cper-cxl-component.json",
{ "cxlComponentEventLog" } },
+ { "./sections/cper-ia32x64-processor.json",
+ { "addressSpace", "errorType", "participationType",
+ "timedOut", "level", "operation", "preciseIP",
+ "restartableIP", "overflow", "uncorrected",
+ "transactionType" } },
};
nlohmann::json loadJson(const char *filePath)
@@ -121,22 +126,26 @@
}
// Document loader callback function
-const nlohmann::json *documentLoader(const std::string &uri)
+const nlohmann::json *documentLoader(const std::string &uri,
+ AddRequiredProps add_required_props)
{
// Load the schema from a file
- nlohmann::json *ref_schema = new nlohmann::json;
+ std::unique_ptr<nlohmann::json> ref_schema =
+ std::make_unique<nlohmann::json>();
*ref_schema = loadJson(uri.c_str());
if (ref_schema->is_discarded()) {
std::cerr << "Could not open schema file: " << uri << std::endl;
}
- std::vector<std::string> opt = {};
- const auto it_optional_file = optional_properties_map.find(uri);
- if (it_optional_file != optional_properties_map.end()) {
- opt = it_optional_file->second;
+ if (add_required_props == AddRequiredProps::YES) {
+ std::vector<std::string> opt = {};
+ const auto it_optional_file = optional_properties_map.find(uri);
+ if (it_optional_file != optional_properties_map.end()) {
+ opt = it_optional_file->second;
+ }
+ iterate_make_required_props(*ref_schema, opt);
}
- iterate_make_required_props(*ref_schema, opt);
- return ref_schema;
+ return ref_schema.release();
}
// Document release callback function
@@ -145,20 +154,19 @@
delete adapter; // Free the adapter memory
}
-int schema_validate_from_file(const char *schema_file_path,
- nlohmann::json &jsonData,
- std::string &error_message)
+std::unique_ptr<valijson::Schema>
+load_schema(AddRequiredProps add_required_props, int single_section)
{
// Load the schema
- nlohmann::json schema_root = loadJson(schema_file_path);
- if (schema_root.is_discarded()) {
- std::cerr << "Could not open schema file: " << schema_file_path
- << std::endl;
- return 0;
- }
+ fs::path pathObj(LIBCPER_JSON_SPEC);
- fs::path pathObj(schema_file_path);
- fs::path base_path = pathObj.parent_path();
+ if (single_section) {
+ pathObj /= "cper-json-section-log.json";
+ } else {
+ pathObj /= "cper-json-full-log.json";
+ }
+ nlohmann::json schema_root = loadJson(pathObj.c_str());
+ fs::path base_path(LIBCPER_JSON_SPEC);
try {
fs::current_path(base_path);
// std::cout << "Changed directory to: " << fs::current_path()
@@ -168,21 +176,31 @@
}
// Parse the json schema into an internal schema format
- valijson::Schema schema;
+ std::unique_ptr<valijson::Schema> schema =
+ std::make_unique<valijson::Schema>();
valijson::SchemaParser parser;
valijson::adapters::NlohmannJsonAdapter schemaDocumentAdapter(
schema_root);
// Set up callbacks for resolving external references
try {
- parser.populateSchema(schemaDocumentAdapter, schema,
- documentLoader, documentRelease);
+ parser.populateSchema(
+ schemaDocumentAdapter, *schema,
+ [add_required_props](const std::string &uri) {
+ return documentLoader(uri, add_required_props);
+ },
+ documentRelease);
} catch (std::exception &e) {
std::cerr << "Failed to parse schema: " << e.what()
<< std::endl;
- return 0;
}
+ return schema;
+}
+int schema_validate_from_file(const valijson::Schema &schema,
+ nlohmann::json &jsonData,
+ std::string &error_message)
+{
// Perform validation
valijson::Validator validator(valijson::Validator::kStrongTypes);
valijson::ValidationResults results;
diff --git a/tests/test-utils.hpp b/tests/test-utils.hpp
index 42e41bc..ec5f064 100644
--- a/tests/test-utils.hpp
+++ b/tests/test-utils.hpp
@@ -13,12 +13,23 @@
#include <libcper/generator/sections/gen-section.h>
}
+// Controls whether required properties are added to the majority of property
+// definitions. This is useful for unit tests that are validating JSON where
+// all fields are valid
+enum class AddRequiredProps { YES, NO };
+
FILE *generate_record_memstream(const char **types, UINT16 num_types,
char **buf, size_t *buf_size,
int single_section,
GEN_VALID_BITS_TEST_TYPE validBitsType);
-int schema_validate_from_file(const char *file_path, nlohmann::json &jsonData,
+
+std::unique_ptr<valijson::Schema>
+load_schema(AddRequiredProps add_required_props, int single_section);
+
+int schema_validate_from_file(const valijson::Schema &schema,
+ nlohmann::json &jsonData,
std::string &error_message);
+
nlohmann::json loadJson(const char *filePath);
#endif