Finish JSON validator, add debug out.
diff --git a/json-schema.c b/json-schema.c
index 10fbb0a..44ca8c4 100644
--- a/json-schema.c
+++ b/json-schema.c
@@ -10,16 +10,23 @@
 #include <unistd.h>
 #include <libgen.h>
 #include <limits.h>
+#include <stdarg.h>
 #include "json.h"
 #include "json-schema.h"
 #include "edk/BaseTypes.h"
 
+//Field definitions.
+int json_validator_debug = 0;
+
 //Private pre-definitions.
 int validate_field(const char* name, json_object* schema, json_object* object, char* error_message);
 int validate_integer(const char* field_name, json_object* schema, json_object* object, char* error_message);
 int validate_string(const char* field_name, json_object* schema, json_object* object, char* error_message);
 int validate_object(const char* field_name, json_object* schema, json_object* object, char* error_message);
 int validate_array(const char* field_name, json_object* schema, json_object* object, char* error_message);
+void log_validator_error(char* error_message, const char* format, ...);
+void log_validator_debug(const char* format, ...);
+void log_validator_msg(const char* format, va_list args);
 
 //Validates a single JSON object against a provided schema file, returning 1 on success and 0 on failure to validate.
 //Error message space must be allocated prior to call.
@@ -29,7 +36,7 @@
     json_object* schema_ir = json_object_from_file(schema_file);
     if (schema_ir == NULL)
     {
-        sprintf(error_message, "Failed to load schema from file '%s'.", schema_file);
+        log_validator_error(error_message, "Failed to load schema from file '%s'.", schema_file);
         return 0;
     }
 
@@ -55,7 +62,7 @@
     json_object* schema_ver = json_object_object_get(schema, "$schema");
     if (schema_ver == NULL || strcmp(json_object_get_string(schema_ver), JSON_SCHEMA_VERSION))
     {
-        sprintf(error_message, "Provided schema is not of the same version that is referenced by this validator, or is not a schema.");
+        log_validator_error(error_message, "Provided schema is not of the same version that is referenced by this validator, or is not a schema.");
         return 0;
     }
 
@@ -63,12 +70,12 @@
     char* original_cwd = malloc(PATH_MAX);
     if (getcwd(original_cwd, PATH_MAX) == NULL)
     {
-        sprintf(error_message, "Failed fetching the current directory.");
+        log_validator_error(error_message, "Failed fetching the current directory.");
         return 0;
     }
     if (chdir(schema_directory))
     {
-        sprintf(error_message, "Failed to chdir into schema directory.");
+        log_validator_error(error_message, "Failed to chdir into schema directory.");
         return 0;
     }
 
@@ -83,28 +90,35 @@
 }
 
 //Validates a single JSON field given a schema/object.
+//Returns -1 on fatal/error failure, 0 on validation failure, and 1 on validation.
 int validate_field(const char* field_name, json_object* schema, json_object* object, char* error_message)
 {
+    log_validator_debug("Validating field '%s'...", field_name);
+
     //If there is a "$ref" field, attempt to load the referenced schema.
     json_object* ref_schema = json_object_object_get(schema, "$ref");
     if (ref_schema != NULL && json_object_get_type(ref_schema) == json_type_string)
     {
+        log_validator_debug("$ref schema detected for field '%s'.", field_name);
+
         //Attempt to load. If loading fails, report error.
         const char* ref_path = json_object_get_string(ref_schema);
         schema = json_object_from_file(ref_path);
         if (schema == NULL)
         {
-            sprintf(error_message, "Failed to open referenced schema file '%s'.", ref_path);
-            return 0;
+            log_validator_error(error_message, "Failed to open referenced schema file '%s'.", ref_path);
+            return -1;
         }
+
+        log_validator_debug("loaded schema path '%s' for field '%s'.", ref_path, field_name);
     }
 
     //Get the schema field type.
     json_object* desired_field_type = json_object_object_get(schema, "type");
     if (desired_field_type == NULL || !json_object_is_type(desired_field_type, json_type_string))
     {
-        sprintf(error_message, "Desired field type not provided within schema/is not a string for field '%s' (schema violation).", field_name);
-        return 0;
+        log_validator_error(error_message, "Desired field type not provided within schema/is not a string for field '%s' (schema violation).", field_name);
+        return -1;
     }
 
     //Check the field types are actually equal.
@@ -118,11 +132,44 @@
         || (!strcmp(desired_field_type_str, "double") && json_object_is_type(object, json_type_double))
     ))
     {
-        sprintf(error_message, "Field type match failed for field '%s'.", field_name);
+        log_validator_error(error_message, "Field type match failed for field '%s'.", field_name);
         return 0;
     }
 
-    //todo: support oneOf
+    //If the schema contains a "oneOf" array, we need to validate the field against each of the
+    //possible options in turn.
+    json_object* one_of = json_object_object_get(schema, "oneOf");
+    if (one_of != NULL && json_object_get_type(one_of) == json_type_array)
+    {
+        log_validator_debug("oneOf options detected for field '%s'.", field_name);
+
+        int len = json_object_array_length(one_of);
+        int validated = 0;
+        for (int i=0; i<len; i++)
+        {
+            //If the "oneOf" member isn't an object, warn on schema violation.
+            json_object* one_of_option = json_object_array_get_idx(one_of, i);
+            if (one_of_option == NULL || json_object_get_type(one_of_option) != json_type_object)
+            {
+                log_validator_debug("Schema Warning: 'oneOf' member for field '%s' is not an object, schema violation.", field_name);
+                continue;
+            }
+
+            //Validate field with schema.
+            validated = validate_field(field_name, one_of_option, object, error_message);
+            if (validated == -1)
+                return -1;
+            if (validated)
+                break;
+        }
+
+        //Return if failed all checks.
+        if (!validated) 
+        {
+            log_validator_error(error_message, "No schema object structures matched provided object for field '%s'.", field_name);
+            return 0;
+        }
+    }
 
     //Switch and validate each type in turn.
     switch (json_object_get_type(object))
@@ -134,10 +181,11 @@
         case json_type_object:
             return validate_object(field_name, schema, object, error_message);
         case json_type_array:
-            return validate_object(field_name, schema, object, error_message);
+            return validate_array(field_name, schema, object, error_message);
 
         //We don't perform extra validation on this type.
         default:
+            log_validator_debug("validation passed for '%s' (no extra validation).", field_name);
             return 1;
     }
 }
@@ -153,7 +201,7 @@
         int min_value_int = json_object_get_int(min_value);
         if (json_object_get_uint64(object) < min_value_int)
         {
-            sprintf(error_message, "Failed to validate integer field '%s'. Value was below minimum of %d.", field_name, min_value_int);
+            log_validator_error(error_message, "Failed to validate integer field '%s'. Value was below minimum of %d.", field_name, min_value_int);
             return 0;
         }
     }
@@ -165,7 +213,7 @@
         int max_value_int = json_object_get_int(max_value);
         if (json_object_get_uint64(object) > max_value_int)
         {
-            sprintf(error_message, "Failed to validate integer field '%s'. Value was above maximum of %d.", field_name, max_value_int);
+            log_validator_error(error_message, "Failed to validate integer field '%s'. Value was above maximum of %d.", field_name, max_value_int);
             return 0;
         }
     }
@@ -187,6 +235,8 @@
     json_object* required_fields = json_object_object_get(schema, "required");
     if (required_fields != NULL && json_object_get_type(required_fields) == json_type_array)
     {
+        log_validator_debug("Required fields found for '%s', matching...", field_name);
+
         int len = json_object_array_length(required_fields);
         for (int i=0; i<len; i++)
         {
@@ -194,7 +244,7 @@
             json_object* required_field = json_object_array_get_idx(required_fields, i);
             if (json_object_get_type(required_field) != json_type_string)
             {
-                sprintf(error_message, "Required field for object '%s' is not a string (schema violation).", field_name);
+                log_validator_error(error_message, "Required field for object '%s' is not a string (schema violation).", field_name);
                 return 0;
             }
 
@@ -202,7 +252,7 @@
             const char* required_field_str = json_object_get_string(required_field);
             if (json_object_object_get(object, required_field_str) == NULL)
             {
-                sprintf(error_message, "Required field '%s' was not present in object '%s'.", required_field_str, field_name);
+                log_validator_error(error_message, "Required field '%s' was not present in object '%s'.", required_field_str, field_name);
                 return 0;
             }
         }
@@ -248,4 +298,52 @@
     }
 
     return 1;
+}
+
+//Enables/disables debugging globally for the JSON validator.
+void validate_schema_debug_enable() { json_validator_debug = 1; }
+void validate_schema_debug_disable() { json_validator_debug = 0; }
+
+//Logs an error message to the given character and (optionally) provides debug output.
+void log_validator_error(char* error_message, const char* format, ...)
+{
+    va_list args;
+
+    //Log error to error out.
+    va_start(args, format);
+    vsnprintf(error_message, JSON_ERROR_MSG_MAX_LEN, format, args);
+    va_end(args);
+    
+    //Debug message if necessary.
+    va_start(args, format);
+    log_validator_msg(format, args);
+    va_end(args);
+}
+
+//Logs a debug message to the given character and (optionally) provides debug output.
+void log_validator_debug(const char* format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    log_validator_msg(format, args);
+    va_end(args);
+}
+
+//Logs a single validator debug/error message.
+void log_validator_msg(const char* format, va_list args)
+{
+    //Print debug output if debug is on.
+    if (json_validator_debug)
+    {
+        //Make new format string for error.
+        const char* header = "json_validator: ";
+        char* new_format = malloc(strlen(header) + strlen(format) + 2);
+        strcpy(new_format, header);
+        strcat(new_format, format);
+        strcat(new_format, "\n");
+
+        //Print & free format.
+        vfprintf(stdout, new_format, args);
+        free(new_format);
+    }
 }
\ No newline at end of file
diff --git a/json-schema.h b/json-schema.h
index 997736d..d5751c6 100644
--- a/json-schema.h
+++ b/json-schema.h
@@ -4,8 +4,11 @@
 #include "json.h"
 
 #define JSON_SCHEMA_VERSION "https://json-schema.org/draft/2020-12/schema"
+#define JSON_ERROR_MSG_MAX_LEN 512
 
 int validate_schema(json_object* schema, char* schema_directory, json_object* object, char* error_message);
 int validate_schema_from_file(const char* schema_file, json_object* object, char* error_message);
+void validate_schema_debug_enable();
+void validate_schema_debug_disable();
 
 #endif
\ No newline at end of file
diff --git a/specification/json/cper-json-section-descriptor.json b/specification/json/cper-json-section-descriptor.json
index 6148a5b..438e28a 100644
--- a/specification/json/cper-json-section-descriptor.json
+++ b/specification/json/cper-json-section-descriptor.json
@@ -69,13 +69,13 @@
         },
         "sectionType": {
             "type": "object",
-            "required": ["data", "name"],
+            "required": ["data", "type"],
             "properties": {
                 "data": {
                     "type": "string",
                     "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{16}$"
                 },
-                "name": {
+                "type": {
                     "type": "string"
                 }
             }
diff --git a/specification/json/cper-json.json b/specification/json/cper-json.json
index e0e7133..302adc9 100644
--- a/specification/json/cper-json.json
+++ b/specification/json/cper-json.json
@@ -35,7 +35,8 @@
                     { "$ref": "./sections/cper-iommu-dmar.json" },
                     { "$ref": "./sections/cper-ccix-per.json" },
                     { "$ref": "./sections/cper-cxl-protocol.json" },
-                    { "$ref": "./sections/cper-cxl-component.json" }
+                    { "$ref": "./sections/cper-cxl-component.json" },
+                    { "$ref": "./sections/cper-unknown.json" }
                 ]
             }
         }
diff --git a/specification/json/sections/cper-arm-processor.json b/specification/json/sections/cper-arm-processor.json
index 4e473fc..ccad75b 100644
--- a/specification/json/sections/cper-arm-processor.json
+++ b/specification/json/sections/cper-arm-processor.json
@@ -96,7 +96,16 @@
                     },
                     "multipleError": {
                         "type": "object",
-                        "$ref": "./common/cper-json-nvp.json"
+                        "required": ["type", "value"],
+                        "additionalProperties": false,
+                        "properties": {
+                            "type": {
+                                "type": "string"
+                            },
+                            "value": {
+                                "type": "integer"
+                            }
+                        }
                     },
                     "flags": {
                         "type": "object",
diff --git a/specification/json/sections/cper-unknown.json b/specification/json/sections/cper-unknown.json
new file mode 100644
index 0000000..ea8c8f0
--- /dev/null
+++ b/specification/json/sections/cper-unknown.json
@@ -0,0 +1,12 @@
+{
+    "$id": "cper-json-unknown-section",
+    "$schema": "https://json-schema.org/draft/2020-12/schema",
+    "type": "object",
+    "required": ["data"],
+    "additionalProperties": false,
+    "properties": {
+        "data": {
+            "type": "string"
+        }
+    }
+}
\ No newline at end of file
diff --git a/testing/cper-test.c b/testing/cper-test.c
index ca698b3..d5e8f5b 100644
--- a/testing/cper-test.c
+++ b/testing/cper-test.c
@@ -22,7 +22,8 @@
     if (argc >= 3)
     {
         printf("Validating output with specification %s...\n", argv[2]);
-        char* error_message = malloc(300);
+        validate_schema_debug_enable();
+        char* error_message = malloc(JSON_ERROR_MSG_MAX_LEN);
         if (!validate_schema_from_file(argv[2], ir, error_message))
         {
             printf("Validation failed: %s\n", error_message);