#include #include #include #include #include #include "validate.h" json_object *json = NULL; json_object *schema = NULL; json_object *defs = NULL; static char *schemavalidator_errstr[SCHEMAVALIDATOR_ERR_MAX] = { "VALID", "GENERAL ERROR", "JSON FILE NOT FOUND", "SCHEMA FILE NOT FOUND", "WRONG ARGUEMNTS GIVEN", "SCHEMA ERROR", "INVALID", "REGEX MISMATCH", "REGEX MATCH", "REGEX COMPILE FAILED" }; const char *schemavalidator_errorstr(unsigned int schemavalidator_errors) { if (schemavalidator_errors < SCHEMAVALIDATOR_ERR_MAX) { return schemavalidator_errstr[schemavalidator_errors]; } return NULL; } int _schemavalidator_load(const char *jsonfile, const char *jsonschema) { json = json_object_from_file(jsonfile); if (json == NULL) { return SCHEMAVALIDATOR_ERR_JSON_NOT_FOUND; } schema = json_object_from_file(jsonschema); if (schema == NULL) { json_object_put(json); return SCHEMAVALIDATOR_ERR_SCHEMA_NOT_FOUND; } return SCHEMAVALIDATOR_ERR_VALID; } int __schemavalidator_inspect_type(json_object *jobj, const char *type, json_object *joutput_node) { if (strcmp(type, "object") == 0) { if (json_object_is_type(jobj, json_type_object)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "array") == 0) { if (json_object_is_type(jobj, json_type_array)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "string") == 0) { if (json_object_is_type(jobj, json_type_string)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "integer") == 0) { if (json_object_is_type(jobj, json_type_int)) { return SCHEMAVALIDATOR_ERR_VALID; } if (json_object_is_type(jobj, json_type_double)) { double value = json_object_get_double(jobj); if (value == round(value)) { // "zero fractional part is an integer" return SCHEMAVALIDATOR_ERR_VALID; } } } else if (strcmp(type, "double") == 0) { if (json_object_is_type(jobj, json_type_double)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "number") == 0) { if (json_object_is_type(jobj, json_type_double) || json_object_is_type(jobj, json_type_int)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "boolean") == 0) { if (json_object_is_type(jobj, json_type_boolean)) { return SCHEMAVALIDATOR_ERR_VALID; } } else if (strcmp(type, "null") == 0) { if (json_object_is_type(jobj, json_type_null)) { return SCHEMAVALIDATOR_ERR_VALID; } } else { printf("WARN unknown type in check type %s\n", type); json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "type"); _schemavalidator_output_apply_result( jnode, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "type"); _schemavalidator_output_apply_result(jnode, SCHEMAVALIDATOR_ERR_INVALID); return SCHEMAVALIDATOR_ERR_INVALID; } int schemavalidator_check_bool(json_object *jobj, json_object *jschema, json_object *joutput_node) { (void)jobj; // check if jschema is a bool, true or false int err; if (json_object_is_type(jschema, json_type_boolean)) { json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "bool"); json_bool value = json_object_get_boolean(jschema); err = value == 0 ? SCHEMAVALIDATOR_ERR_INVALID : SCHEMAVALIDATOR_ERR_VALID; _schemavalidator_output_apply_result(jnode, err); return err; } return SCHEMAVALIDATOR_ERR_VALID; } int _schemavalidator_check_type(json_object *jobj, json_object *jschema, json_object *joutput_node) { json_object *jnode; json_object *jtype = json_object_object_get(jschema, "type"); if (jtype == NULL) { return SCHEMAVALIDATOR_ERR_VALID; } if (json_object_is_type(jtype, json_type_string)) { const char *type = json_object_get_string(jtype); return __schemavalidator_inspect_type(jobj, type, joutput_node); } if (json_object_is_type(jtype, json_type_array)) { int arraylen = json_object_array_length(jtype); for (int i = 0; i < arraylen; i++) { json_object *iobj = json_object_array_get_idx(jtype, i); if (!json_object_is_type(iobj, json_type_string)) { goto check_type_schema_error; } const char *type = json_object_get_string(iobj); int err = __schemavalidator_inspect_type(jobj, type, joutput_node); if (err == SCHEMAVALIDATOR_ERR_VALID) { return SCHEMAVALIDATOR_ERR_VALID; } } jnode = _schemavalidator_output_create_and_append_node( joutput_node, "type"); _schemavalidator_output_apply_result( jnode, SCHEMAVALIDATOR_ERR_INVALID); return SCHEMAVALIDATOR_ERR_INVALID; } check_type_schema_error: jnode = _schemavalidator_output_create_and_append_node(joutput_node, "type"); _schemavalidator_output_apply_result(jnode, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } int _schemavalidator_check_required(json_object *jobj, json_object *jschema, json_object *joutput_node) { //printf("%s\n%s\n", __func__, json_object_to_json_string(jobj)); json_object *jarray = json_object_object_get(jschema, "required"); if (!jarray) { return SCHEMAVALIDATOR_ERR_VALID; } json_object *jrequired_node = _schemavalidator_output_create_and_append_node(joutput_node, "required"); int missing_required_key = 0; int arraylen = json_object_array_length(jarray); for (int i = 0; i < arraylen; i++) { json_object *iobj = json_object_array_get_idx(jarray, i); const char *key = json_object_get_string(iobj); if (key) { //printf("%s\n", key); // use json_object_object_get_ex becuase of json_type_null types json_object *required_object = NULL; int err = json_object_object_get_ex(jobj, key, &required_object); if (err == 0) { // printf("required key missing: %s\n", key); json_object *jkeynode = _schemavalidator_output_create_and_append_node( jrequired_node, key); _schemavalidator_output_apply_result( jkeynode, SCHEMAVALIDATOR_ERR_INVALID); missing_required_key = 1; } } } int ret = missing_required_key == 1 ? SCHEMAVALIDATOR_ERR_INVALID : SCHEMAVALIDATOR_ERR_VALID; _schemavalidator_output_apply_result(jrequired_node, ret); return ret; } int _schemavalidator_check_properties(json_object *jobj, json_object *jschema, json_object *joutput_node) { // printf("%s\n", __func__); json_object *jprops = json_object_object_get(jschema, "properties"); if (!jprops) { return SCHEMAVALIDATOR_ERR_VALID; } json_object *jproperties_node = _schemavalidator_output_create_and_append_node(joutput_node, "properties"); int properties_valid = 1; json_object_object_foreach(jprops, jprop_key, jprop_val) { // printf("key of prop is %s\n", jprop_key); json_object *iobj = json_object_object_get(jobj, jprop_key); //printf("iobj %s type %d\nkey %s\nval %s\n", json_object_get_string(iobj), json_object_get_type(iobj), jprop_key, json_object_get_string(jprop_val)); if (iobj) { json_object *jprop_item_tmp_node = _schemavalidator_output_create_node(jprop_key); int err = _schemavalidator_validate_instance( iobj, jprop_val, jprop_item_tmp_node); if (err != SCHEMAVALIDATOR_ERR_VALID) { properties_valid = 0; _schemavalidator_output_apply_result( jprop_item_tmp_node, err); _schemavalidator_output_append_node( jproperties_node, jprop_item_tmp_node); } else { json_object_put(jprop_item_tmp_node); } } } int ret = properties_valid == 1 ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; _schemavalidator_output_apply_result(jproperties_node, ret); return ret; } int _schemavalidator_check_prefixItems_and_items(json_object *jobj, json_object *jschema, json_object *joutput_node) { json_object *jprefixitems = json_object_object_get(jschema, "prefixItems"); json_object *jitems = json_object_object_get(jschema, "items"); int prefixitems_ok = 1; int items_ok = 1; if (jprefixitems) { json_object *jprefixitems_node = _schemavalidator_output_create_and_append_node( joutput_node, "prefixItems"); if (!json_object_is_type(jprefixitems, json_type_array)) { _schemavalidator_output_apply_result( jprefixitems_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } int jobj_arraylen = json_object_array_length(jobj); int prefixitems_arraylen = json_object_array_length(jprefixitems); for (int i = 0; i < jobj_arraylen && i < prefixitems_arraylen; i++) { //printf("i=%d prefixitems\n", i); json_object *iobj = json_object_array_get_idx(jobj, i); json_object *ischema = json_object_array_get_idx(jprefixitems, i); char numstr[12]; snprintf(numstr, sizeof(numstr), "%d", i); json_object *jarrayitem_tmp_node = _schemavalidator_output_create_node(numstr); int err = _schemavalidator_validate_instance( iobj, ischema, jarrayitem_tmp_node); if (err) { _schemavalidator_output_apply_result( jprefixitems_node, err); _schemavalidator_output_append_node( jprefixitems_node, jarrayitem_tmp_node); prefixitems_ok = 0; } else { json_object_put(jarrayitem_tmp_node); } } int prefixitems_ret = (prefixitems_ok == 1) ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; _schemavalidator_output_apply_result(jprefixitems_node, prefixitems_ret); } if (jitems) { json_object *jitems_node = _schemavalidator_output_create_and_append_node( joutput_node, "items"); if (!json_object_is_type(jitems, json_type_object) && !json_object_is_type(jitems, json_type_boolean)) { _schemavalidator_output_apply_result( jitems_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } int jobj_arraylen = json_object_array_length(jobj); int items_arraylen = 0; for (int i = items_arraylen; i < jobj_arraylen; i++) { //printf("i=%d items\n", i); json_object *iobj = json_object_array_get_idx(jobj, i); char numstr[12]; snprintf(numstr, sizeof(numstr), "%d", i); json_object *jarrayitem_tmp_node = _schemavalidator_output_create_node(numstr); int err = _schemavalidator_validate_instance( iobj, jitems, jarrayitem_tmp_node); if (err) { _schemavalidator_output_apply_result( jarrayitem_tmp_node, err); _schemavalidator_output_append_node( jitems_node, jarrayitem_tmp_node); items_ok = 0; } else { json_object_put(jarrayitem_tmp_node); } } int items_ret = (items_ok == 1) ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; _schemavalidator_output_apply_result(jitems_node, items_ret); } int ret = (prefixitems_ok == 1 && items_ok == 1) ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; return ret; } int _schemavalidator_value_is_equal(json_object *jobj1, json_object *jobj2) { if (json_object_equal(jobj1, jobj2)) { return SCHEMAVALIDATOR_ERR_VALID; } if (json_object_is_type(jobj1, json_type_double) && json_object_is_type(jobj2, json_type_int)) { double value = json_object_get_double(jobj1); double value2 = json_object_get_int64(jobj2); if (value == round(value) && value == value2) { return SCHEMAVALIDATOR_ERR_VALID; } } if (json_object_is_type(jobj1, json_type_int) && json_object_is_type(jobj2, json_type_double)) { double value = json_object_get_double(jobj2); double value2 = json_object_get_int64(jobj1); if (value == round(value) && value == value2) { return SCHEMAVALIDATOR_ERR_VALID; } } return SCHEMAVALIDATOR_ERR_INVALID; } int _schemavalidator_check_const(json_object *jobj, json_object *jschema, json_object *joutput_node) { json_object *jconst; int err = json_object_object_get_ex(jschema, "const", &jconst); if (err == 0) { return SCHEMAVALIDATOR_ERR_VALID; } err = _schemavalidator_value_is_equal(jobj, jconst); if (err == SCHEMAVALIDATOR_ERR_VALID) { return SCHEMAVALIDATOR_ERR_VALID; } json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "const"); _schemavalidator_output_apply_result(jnode, SCHEMAVALIDATOR_ERR_INVALID); return SCHEMAVALIDATOR_ERR_INVALID; } int _schemavalidator_check_enums(json_object *jobj, json_object *jschema, json_object *joutput_node) { json_object *jenum_array = json_object_object_get(jschema, "enum"); if (!jenum_array) { return SCHEMAVALIDATOR_ERR_VALID; } if (!json_object_is_type(jenum_array, json_type_array)) { json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "enum"); _schemavalidator_output_apply_result( jnode, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } int arraylen = json_object_array_length(jenum_array); for (int i = 0; i < arraylen; i++) { json_object *ienum = json_object_array_get_idx(jenum_array, i); int err = _schemavalidator_value_is_equal(jobj, ienum); if (err == SCHEMAVALIDATOR_ERR_VALID) { return SCHEMAVALIDATOR_ERR_VALID; } } // printf("ERROR: enum check failed (%s not in enum)\n", json_object_to_json_string(jobj)); json_object *jnode = _schemavalidator_output_create_and_append_node( joutput_node, "enum"); _schemavalidator_output_apply_result(jnode, SCHEMAVALIDATOR_ERR_INVALID); return SCHEMAVALIDATOR_ERR_INVALID; } int _schemavalidator_check_uniqueItems(json_object *jobj, json_object *jschema, json_object *joutput_node) { json_object *juniq = json_object_object_get(jschema, "uniqueItems"); if (!juniq) { return SCHEMAVALIDATOR_ERR_VALID; } json_object *juniqueitems_node = _schemavalidator_output_create_and_append_node(joutput_node, "uniqueItems"); if (!json_object_is_type(juniq, json_type_boolean)) { _schemavalidator_output_apply_result( juniqueitems_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } // uniqueItems=false is valid if (json_object_get_boolean(juniq) == 0) { _schemavalidator_output_apply_result(juniqueitems_node, SCHEMAVALIDATOR_ERR_VALID); return SCHEMAVALIDATOR_ERR_VALID; } int uniqueitems_ok = 1; int arraylen = json_object_array_length(jobj); for (int i = 0; i < arraylen - 1; i++) { json_object *iobj = json_object_array_get_idx(jobj, i); for (int j = i + 1; j < arraylen; j++) { json_object *uobj = json_object_array_get_idx(jobj, j); if (json_object_equal(iobj, uobj) == 1) { uniqueitems_ok = 0; char numstr[12]; snprintf(numstr, sizeof(numstr), "%d", i); json_object *jnotunique_node = _schemavalidator_output_create_and_append_node( juniqueitems_node, numstr); _schemavalidator_output_apply_result( jnotunique_node, SCHEMAVALIDATOR_ERR_INVALID); } } } int ret = uniqueitems_ok == 1 ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; _schemavalidator_output_apply_result(juniqueitems_node, ret); return ret; } int _schemavalidator_check_maxmin_items(json_object *jobj, json_object *jschema, json_object *joutput_node) { int err = SCHEMAVALIDATOR_ERR_VALID; int arraylen = json_object_array_length(jobj); json_object *jmax = json_object_object_get(jschema, "maxItems"); if (jmax) { if (json_object_is_type(jmax, json_type_int) || json_object_is_type(jmax, json_type_double)) { int maxitems = json_object_get_double(jmax); if (arraylen > maxitems) { json_object *jmaxitems_node = _schemavalidator_output_create_and_append_node( joutput_node, "maxItems"); _schemavalidator_output_apply_result( jmaxitems_node, SCHEMAVALIDATOR_ERR_INVALID); err = SCHEMAVALIDATOR_ERR_INVALID; } } } json_object *jmin = json_object_object_get(jschema, "minItems"); if (jmin) { if (json_object_is_type(jmin, json_type_int) || json_object_is_type(jmin, json_type_double)) { int minitems = json_object_get_double(jmin); if (arraylen < minitems) { json_object *jminitems_node = _schemavalidator_output_create_and_append_node( joutput_node, "minItems"); _schemavalidator_output_apply_result( jminitems_node, SCHEMAVALIDATOR_ERR_INVALID); err = SCHEMAVALIDATOR_ERR_INVALID; } } } // if (err) // printf("ERROR: failed at maxItems or minItems check\n"); return err; } int _schemavalidator_validate_array(json_object *jobj, json_object *jschema, json_object *joutput_node) { int err; err = _schemavalidator_check_prefixItems_and_items(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_uniqueItems(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_maxmin_items(jobj, jschema, joutput_node); if (err) { return err; } return SCHEMAVALIDATOR_ERR_VALID; } int _schemavalidator_validate_object(json_object *jobj, json_object *jschema, json_object *joutput_node) { int err; if (defs == NULL) { defs = json_object_object_get(jschema, "$defs"); } err = _schemavalidator_check_required(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_properties(jobj, jschema, joutput_node); if (err) { return err; } return SCHEMAVALIDATOR_ERR_VALID; } int utf8_length(const char *str) { const char *pointer = str; int len = 0; while (pointer[0]) { if ((pointer[0] & 0xC0) != 0x80) { len++; } pointer++; } return len; } int _schemavalidator_validate_string(json_object *jobj, json_object *jschema, json_object *joutput_node) { const char *str = json_object_get_string(jobj); //printf("strlen of %s %ld %d %d\n", str, strlen(str), json_object_get_string_len(jobj), utf8_length(str)); int minlength_ok = 1; json_object *jminlen = json_object_object_get(jschema, "minLength"); if (jminlen) { int minlen = json_object_get_int64(jminlen); if (utf8_length(str) < minlen) { minlength_ok = 0; json_object *jminlength_node = _schemavalidator_output_create_and_append_node( joutput_node, "minLength"); _schemavalidator_output_apply_result( jminlength_node, SCHEMAVALIDATOR_ERR_INVALID); } } int maxlength_ok = 1; json_object *jmaxlen = json_object_object_get(jschema, "maxLength"); if (jmaxlen) { int maxlen = json_object_get_int64(jmaxlen); if (utf8_length(str) > maxlen) { maxlength_ok = 0; json_object *jmaxlength_node = _schemavalidator_output_create_and_append_node( joutput_node, "maxLength"); _schemavalidator_output_apply_result( jmaxlength_node, SCHEMAVALIDATOR_ERR_INVALID); } } int enums_ok = 1; int err = _schemavalidator_check_enums(jobj, jschema, joutput_node); if (err) { if (err == SCHEMAVALIDATOR_ERR_SCHEMA_ERROR) { // _schemavalidator_output_apply_result(joutput_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return err; } enums_ok = 0; } int ret = minlength_ok == 1 && maxlength_ok == 1 && enums_ok == 1 ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; // _schemavalidator_output_apply_result(joutput_node, ret); return ret; } int _schemavalidator_validate_integer(json_object *jobj, json_object *jschema, json_object *joutput_node) { (void)jobj; double value = (double)json_object_get_int64(jobj); int err = _schemavalidator_validate_number(jobj, jschema, value, joutput_node); return err; } int _schemavalidator_validate_double(json_object *jobj, json_object *jschema, json_object *joutput_node) { (void)jobj; double value = json_object_get_double(jobj); int err = _schemavalidator_validate_number(jobj, jschema, value, joutput_node); return err; } int _schemavalidator_validate_number(json_object *jobj, json_object *jschema, double value, json_object *joutput_node) { (void)jobj; int multipleOf_ok = 1; json_object *jmult = json_object_object_get(jschema, "multipleOf"); if (jmult) { double multipland = (double)json_object_get_double(jmult); if (multipland == 0.0) { json_object *jmultipleOf_node = _schemavalidator_output_create_and_append_node( joutput_node, "multipleOf"); _schemavalidator_output_apply_result( jmultipleOf_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); // _schemavalidator_output_apply_result(joutput_node, SCHEMAVALIDATOR_ERR_SCHEMA_ERROR); return SCHEMAVALIDATOR_ERR_SCHEMA_ERROR; } double divided = value / multipland; if (isinf(divided) != 0 || divided != round(divided)) { multipleOf_ok = 0; } if (multipleOf_ok == 0) { json_object *jmultipleOf_node = _schemavalidator_output_create_and_append_node( joutput_node, "multipleOf"); _schemavalidator_output_apply_result( jmultipleOf_node, SCHEMAVALIDATOR_ERR_INVALID); } } int minimum_ok = 1; json_object *jmin = json_object_object_get(jschema, "minimum"); if (jmin) { double min = (double)json_object_get_double(jmin); if (value < min) { minimum_ok = 0; json_object *jminimum_node = _schemavalidator_output_create_and_append_node( joutput_node, "minimum"); _schemavalidator_output_apply_result( jminimum_node, SCHEMAVALIDATOR_ERR_INVALID); } } int exclusiveMinimum_ok = 1; json_object *jexclmin = json_object_object_get(jschema, "exclusiveMinimum"); if (jexclmin) { double min = (double)json_object_get_double(jexclmin); if (value <= min) { exclusiveMinimum_ok = 0; json_object *jexclusiveMinimum_node = _schemavalidator_output_create_and_append_node( joutput_node, "exclusiveMinimum"); _schemavalidator_output_apply_result( jexclusiveMinimum_node, SCHEMAVALIDATOR_ERR_INVALID); } } int maximum_ok = 1; json_object *jmax = json_object_object_get(jschema, "maximum"); if (jmax) { double max = (double)json_object_get_double(jmax); if (value > max) { maximum_ok = 0; json_object *jmaximum_node = _schemavalidator_output_create_and_append_node( joutput_node, "maximum"); _schemavalidator_output_apply_result( jmaximum_node, SCHEMAVALIDATOR_ERR_INVALID); } } int exclusiveMaximum_ok = 1; json_object *jexclmax = json_object_object_get(jschema, "exclusiveMaximum"); if (jexclmax) { double max = (double)json_object_get_double(jexclmax); if (value >= max) { exclusiveMaximum_ok = 0; json_object *jexclusiveMaximum_node = _schemavalidator_output_create_and_append_node( joutput_node, "exclusiveMaximum"); _schemavalidator_output_apply_result( jexclusiveMaximum_node, SCHEMAVALIDATOR_ERR_INVALID); } } int ret = multipleOf_ok == 1 && minimum_ok == 1 && exclusiveMinimum_ok == 1 && maximum_ok == 1 && exclusiveMaximum_ok == 1 ? SCHEMAVALIDATOR_ERR_VALID : SCHEMAVALIDATOR_ERR_INVALID; // _schemavalidator_output_apply_result(joutput_node, ret); return ret; } int _schemavalidator_validate_boolean(json_object *jobj, json_object *jschema, json_object *joutput_node) { (void)jobj; (void)jschema; (void)joutput_node; // printf("%s\n", __func__); // _schemavalidator_output_apply_result(joutput_node, SCHEMAVALIDATOR_ERR_VALID); return SCHEMAVALIDATOR_ERR_VALID; } int _schemavalidator_validate_instance(json_object *jobj, json_object *jschema, json_object *joutput_node) { int err; // printf("--validate instance--\n"); // printf("%s\n", json_object_get_string(jobj)); // printf("%s\n", json_object_get_string(jschema)); err = schemavalidator_check_bool(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_type(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_const(jobj, jschema, joutput_node); if (err) { return err; } err = _schemavalidator_check_enums(jobj, jschema, joutput_node); if (err) { return err; } json_type type = json_object_get_type(jobj); if (type == json_type_object) { return _schemavalidator_validate_object(jobj, jschema, joutput_node); } if (type == json_type_array) { return _schemavalidator_validate_array(jobj, jschema, joutput_node); } if (type == json_type_string) { return _schemavalidator_validate_string(jobj, jschema, joutput_node); } if (type == json_type_boolean) { return _schemavalidator_validate_boolean(jobj, jschema, joutput_node); } if (type == json_type_int) { return _schemavalidator_validate_integer(jobj, jschema, joutput_node); } if (type == json_type_double) { return _schemavalidator_validate_double(jobj, jschema, joutput_node); } if (type == json_type_null) { return SCHEMAVALIDATOR_ERR_VALID; } printf("%s: WARN: type %d not handled\n", __func__, type); return SCHEMAVALIDATOR_ERR_VALID; } int schemavalidator_validate(json_object *jobj, json_object *jschema) { json_object *joutput = _schemavalidator_output_create_node("root"); int err = _schemavalidator_validate_instance(jobj, jschema, joutput); _schemavalidator_output_apply_result(joutput, err); if (joutput) { //printf("Basic Output: %s\n", json_object_get_string(joutput)); _schemavalidator_output_print_errors(joutput); } if (joutput) { json_object_put(joutput); } return err; }