diff --git a/src/json-validator.cpp b/src/json-validator.cpp index f8fbc9d2e8342fa9efdf62f6d9da368543b856fe..695308e55b29245e47a3f7ec086f30893c1ddc53 100644 --- a/src/json-validator.cpp +++ b/src/json-validator.cpp @@ -1,5 +1,6 @@ #include <iostream> #include <iomanip> +#include <json-schema.hpp> extern "C" { @@ -16,104 +17,78 @@ extern "C" #include <stdbool.h> #include <json-c/json.h> -} - -#include <json-schema.hpp> -#include <regex.h> - #include "schema.h" #include "json-validator.h" +} using nlohmann::json; using nlohmann::json_uri; using nlohmann::json_schema::json_validator; -bool json_object_validate_schema(nlohmann::json obj, nlohmann::json sch); +bool initialized; -int schema_validator_destroy(void) +bool json_object_validate_schema(json obj, json sch) { - schema_flush_objects(); + /* json-parse the schema */ - return 0; + json_validator validator; // create validator + + try { + validator.set_root_schema(sch); // insert root-schema + } catch (const std::exception &e) { + std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n"; + return 0; + } + + /* json-parse the people - with custom error handler */ + class custom_error_handler : public nlohmann::json_schema::basic_error_handler + { + void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override + { + nlohmann::json_schema::basic_error_handler::error(ptr, instance, message); + std::cerr << "ERROR: '" << ptr << "' - '" << instance << "': " << message << "\n"; + } + }; + + custom_error_handler err; + validator.validate(obj, err); // validate the document + + if (err) + return 0; + return 1; } -int schema_validator_init(void) +int schema_validator_destroy(void) { - schema_setup_json(); + if (!initialized) + return 0; + schema_flush_objects(); + initialized = false; return 0; } -/* -{"jsonrpc":"2.0","id":2,"result":[0,{"netmode":{"repeat":{"network":"string","wireless":"object","connect_bssid":"string"},"repeat_wifilife":{"wifilife":"object"},"sync":{},"sync_wifilife":{}},...} - -*/ -/* -bool schema_validator_validate_rpcd(struct json_object *in, enum schema_call_t type) +int schema_validator_init(void) { - char *obj, *method; - struct json_object *type, *params, *j_obj, *j_method, *args; - - if (type == SCHEMA_INPUT_CALL) { - // TODO: what should be 'failure' policy? - if (!json_object_object_get_ex(in, "method", &type)) - return 1; - if (strncmp(json_object_get_string(type), "call", 5) != 0) - return 1; - if (!json_object_object_get_ex(in, "params", ¶ms)) - return 1; - - object = json_object_array_get_idx(params, 1); - if (!object) - return 0; - obj = json_object_get_string(object); - if (!obj) - return 0; - j_method = json_object_array_get_idx(params, 2); - if (!j_method) - return 0; - method = json_object_get_string(j_method) - if (!method) - return 0; - args = json_object_array_get_idx(params, 3); - if (!args) - return 0; - } else if (type == SCHEMA_OUTPUT_CALL) { - if (!json_object_object_get_ex(in, "method", &type)) - return 1; - if (strncmp(json_object_get_string(type), "call", 5) != 0) - return 1; - if (!json_object_object_get_ex(in, "params", ¶ms)) - return 1; - - object = json_object_array_get_idx(params, 1); - if (!object) - return 0; - obj = json_object_get_string(object); - if (!obj) - return 0; - j_method = json_object_array_get_idx(params, 2); - if (!j_method) - return 0; - method = json_object_get_string(j_method) - if (!method) - return 0; - args = json_object_array_get_idx(params, 3); - if (!args) - return 0; - } + if (initialized) + return 0; - rv = schema_validator_validate(in, obj, , SCHEMA_INPUT_CALL); + schema_setup_json(); + initialized = true; + return 0; } -*/ -bool schema_validator_validate_blob(struct blob_attr *msg, char *object, char *method, enum schema_call_t type) + +bool schema_validator_validate_blob(struct blob_attr *msg, const char *object, const char *method, enum schema_call_t type) { - //struct json_object *definitions, *schema; struct schema_object *s_object; struct schema_method *s_method; - json schema, definitions, obj; + json schema, obj; int rv = 1; - char *str; + char *str, *s; + + + if (!initialized) + return true; s_object = schema_get_object_schema(object); if (!s_object) @@ -126,34 +101,28 @@ bool schema_validator_validate_blob(struct blob_attr *msg, char *object, char *m goto out; if (type == SCHEMA_INPUT_CALL) - schema = json::parse(s_method->input); - //schema = json_tokener_parse(s_method->input); + s = blobmsg_format_json(s_method->b_input, true); else if (type == SCHEMA_OUTPUT_CALL) - schema = json::parse(s_method->output); - //schema = json_tokener_parse(s_method->output); + s = blobmsg_format_json(s_method->b_output, true); else goto out; - if (!schema) + if (!s) goto out; + schema = json::parse(s); str = blobmsg_format_json(msg, true); obj = json::parse(str); + if (s_object->definitions) { - //definitions = json_tokener_parse(s_object->definitions); - definitions = json::parse(s_object->definitions); - if (definitions) - //json_object_object_add(schema, "definitions", definitions); - obj += definitions; + json definitions = json::parse(s_object->definitions); + schema += json::object_t::value_type("definitions", definitions); } - /*std::cout << "jobject" << json_object_get_string(j_object) << std::endl; - std::cout << "schema" << json_object_get_string(schema) << std::endl;*/ - rv = json_object_validate_schema(obj, schema); - //json_object_put(schema); free(str); + free(s); out: return rv; } diff --git a/src/json-validator.h b/src/json-validator.h index 1bf266793b68900b433ab26e46609766db6dd20b..b5c908e32901b5cf26d36765d0b95239397f3d3f 100644 --- a/src/json-validator.h +++ b/src/json-validator.h @@ -14,12 +14,8 @@ enum schema_call_t { int schema_validator_destroy(void); int schema_validator_init(void); -bool schema_validator_validate(struct json_object *j_object, const char *object, const char *method, enum schema_call_t type); -//bool schema_validator_validate(struct json_object *j_object, char *object, char *method, enum schema_call_t type); -//bool json_object_validate_schema_inject_definitions(struct json_object *j_object, struct json_object *definitions, struct json_object *j_schema); -//bool json_object_validate_schema(struct json_object *j_obj, struct json_object *j_schema); -//bool json_object_validate_schema(nlohmann::json obj, nlohmann::json sch); +bool schema_validator_validate_jobj(struct json_object *j_object, char *object, char *method, enum schema_call_t type); bool schema_validator_validate_blob(struct blob_attr *msg, const char *object, const char *method, enum schema_call_t type); #ifdef __cplusplus } diff --git a/src/schema.cpp b/src/schema.cpp index 1cb593d78e7f96a965aeacf16aaea9a8dd672325..db8bc61af7969b88c88757421977ce18e0b6c91d 100644 --- a/src/schema.cpp +++ b/src/schema.cpp @@ -166,6 +166,7 @@ schema_setup_file(const char *path) continue; schema_parse_object(schema_object, object); + fprintf(stderr, "added schema %s\n", schema_object->object_name); } } @@ -184,9 +185,7 @@ schema_setup_file(const char *path) schema_object->definitions = definitions; avl_insert(&s_ctx.schema_objects, &schema_object->avl); - /*avl_for_each_element(&s_ctx.schema_objects, schema_object, avl) { - fprintf(stderr, "%s %d key = %s\n", __func__, __LINE__, (char *) schema_object->avl.key); - }*/ + out: blob_buf_free(&acl); return; @@ -247,7 +246,7 @@ struct schema_object *schema_get_object_schema(const char *object) void schema_setup_json(void) { - int i; + unsigned int i; glob_t gl; avl_init(&s_ctx.schema_objects, avl_strcmp, false, NULL); diff --git a/src/schema.h b/src/schema.h index a2b6802ece46e5d1382704b324216b50c44f98e8..2575a062f9089f4e70649ef56e4f42e81d19e48b 100644 --- a/src/schema.h +++ b/src/schema.h @@ -34,11 +34,11 @@ struct schema_object { struct avl_node avl; }; -extern struct schema_method *schema_get_method_schema(const char *object, const char *method); -extern const char *schema_get_definitions_schema(const char *object); -extern struct schema_object *schema_get_object_schema(const char *object); -extern void schema_setup_json(); -extern void schema_flush_objects(); +struct schema_method *schema_get_method_schema(const char *object, const char *method); +const char *schema_get_definitions_schema(const char *object); +struct schema_object *schema_get_object_schema(const char *object); +void schema_setup_json(); +void schema_flush_objects(); #ifdef __cplusplus }