void array_items_visit(ArrayItems *a, VisitorEnterFunc enter_func, VisitorExitFunc exit_func, void *ctxt) { if (a->generic_validator) { enter_func(NULL, a->generic_validator, ctxt); validator_visit(a->generic_validator, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, a->generic_validator, ctxt, &new_v); if (new_v) { validator_unref(a->generic_validator); a->generic_validator = new_v; } } GList *it = a->validators; while (it) { Validator *v = (Validator *) it->data; enter_func(NULL, v, ctxt); validator_visit(v, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, v, ctxt, &new_v); if (new_v) { validator_unref(v); it->data = new_v; } it = g_list_next(it); } }
static void _visit(Validator *v, VisitorEnterFunc enter_func, VisitorExitFunc exit_func, void *ctxt) { SchemaParsing *s = (SchemaParsing *) v; validator_visit((Validator *)s->definitions, enter_func, exit_func, ctxt); if (s->type_validator) { enter_func(NULL, s->type_validator, ctxt); validator_visit(s->type_validator, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, s->type_validator, ctxt, &new_v); if (new_v) { validator_unref(s->type_validator); s->type_validator = new_v; } } if (s->extends) { enter_func(NULL, s->extends, ctxt); validator_visit(s->extends, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, s->extends, ctxt, &new_v); if (new_v) { validator_unref(s->extends); s->extends = new_v; } } GSList *it = s->validator_combinators; while(it) { Validator *v = it->data; if (!v) continue; enter_func(NULL, v, ctxt); validator_visit(v, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, v, ctxt, &new_v); if (new_v) { validator_unref(v); it->data = new_v; } it = g_slist_next(it); } }
static void unref(Validator *v) { SchemaParsing *s = (SchemaParsing *) v; if (--s->ref_count) return; g_slist_free_full(s->features, _release_feature); validator_unref(s->type_validator); definitions_unref(s->definitions); g_slist_free_full(s->validator_combinators, _release_validator); validator_unref(s->extends); g_free(s->id); g_free(s); }
TEST(TestReference, First) { auto u = uri_resolver_new(); ASSERT_TRUE(u != NULL); auto v = parse_schema( "{" "\"id\": \"file://test.json\"," "\"definitions\": {" "\"b\": {\"type\": \"boolean\"}" "}," "\"type\": \"object\"," "\"properties\": {\"a\": {\"$ref\": \"#/definitions/b\"}}" "}", u, "file://test2.json", NULL, NULL ); ASSERT_TRUE(v != NULL); EXPECT_TRUE(validate_json("{\"a\": true}", v, u, NULL)); EXPECT_FALSE(validate_json("{\"a\": \"b\"}", v, u, NULL)); EXPECT_FALSE(validate_json("{\"a\": null}", v, u, NULL)); validator_unref(v); uri_resolver_free(u); }
static Validator* set_additional_items(Validator *v, Validator *additional) { ArrayValidator *a = (ArrayValidator *) v; if (a->additional_items) validator_unref(a->additional_items); a->additional_items = validator_ref(additional); return v; }
void array_items_add_item(ArrayItems *a, Validator *v) { if (a->generic_validator) validator_unref(a->generic_validator), a->generic_validator = NULL; a->validators = g_list_append(a->validators, v); ++a->validator_count; }
static void _release(Feature *f) { ArrayItems *a = (ArrayItems *) f; if (a->generic_validator) validator_unref(a->generic_validator); g_list_free_full(a->validators, _validator_release); g_free(a); }
void array_items_set_zero_items(ArrayItems *a) { if (a->generic_validator) validator_unref(a->generic_validator), a->generic_validator = NULL; g_list_free_full(a->validators, _validator_release); a->validators = NULL; a->validator_count = 0; }
void array_items_set_generic_item(ArrayItems *a, Validator *v) { // clean up old items before setting general one g_list_free_full(a->validators, _validator_release); a->validators = NULL; if (a->generic_validator) validator_unref(a->generic_validator); a->generic_validator = v; }
void array_validator_release(ArrayValidator *v) { if (v->items) array_items_unref(v->items); if (v->additional_items) validator_unref(v->additional_items); j_release(&v->def_value); g_free(v); }
static void _visit(Validator *v, VisitorEnterFunc enter_func, VisitorExitFunc exit_func, void *ctxt) { ArrayValidator *a = (ArrayValidator *) v; if (a->additional_items) { enter_func(NULL, a->additional_items, ctxt); validator_visit(a->additional_items, enter_func, exit_func, ctxt); Validator *new_v = NULL; exit_func(NULL, a->additional_items, ctxt, &new_v); if (new_v) { validator_unref(a->additional_items); a->additional_items = new_v; } } if (a->items) array_items_visit(a->items, enter_func, exit_func, ctxt); }
void schema_parsing_set_validator(SchemaParsing *s, Validator *v) { validator_unref(s->type_validator); s->type_validator = v; }
static void _release(Feature *f) { AdditionalFeature *a = (AdditionalFeature *) f; validator_unref(a->validator); g_free(a); }
Validator* parse_schema_n(char const *str, size_t len, UriResolver *uri_resolver, char const *root_scope, JschemaErrorFunc error_func, void *error_ctxt) { //JsonSchemaParserTrace(stdout, ">>> "); void *parser = JsonSchemaParserAlloc(malloc); YajlContext yajl_context = { .parser = parser, .parser_ctxt = { .validator = NULL, .error = SEC_OK, }, }; const bool allow_comments = true; #if YAJL_VERSION < 20000 yajl_parser_config yajl_opts = { allow_comments, 0, }; yajl_handle yh = yajl_alloc(&callbacks, &yajl_opts, NULL, &yajl_context); #else yajl_handle yh = yajl_alloc(&callbacks, NULL, &yajl_context); yajl_config(yh, yajl_allow_comments, allow_comments ? 1 : 0); yajl_config(yh, yajl_dont_validate_strings, 1); #endif // YAJL_VERSION if (!yh) { JsonSchemaParserFree(parser, free); return NULL; } if (yajl_status_ok != yajl_parse(yh, (const unsigned char *)str, len)) { if (yajl_context.parser_ctxt.error == SEC_OK) { unsigned char *err = yajl_get_error(yh, 0/*verbose*/, (const unsigned char *)str, len); if (error_func) error_func(yajl_get_bytes_consumed(yh), SEC_SYNTAX, (const char *) err, error_ctxt); yajl_free_error(yh, err); } else { if (error_func) error_func(yajl_get_bytes_consumed(yh), yajl_context.parser_ctxt.error, SchemaGetErrorMessage(yajl_context.parser_ctxt.error), error_ctxt); } yajl_free(yh); JsonSchemaParserFree(parser, free); return NULL; } #if YAJL_VERSION < 20000 if (yajl_status_ok != yajl_parse_complete(yh)) #else if (yajl_status_ok != yajl_complete_parse(yh)) #endif { if (yajl_context.parser_ctxt.error == SEC_OK) { unsigned char *err = yajl_get_error(yh, 0, (const unsigned char *)str, len); if (error_func) error_func(yajl_get_bytes_consumed(yh), SEC_SYNTAX, (const char *) err, error_ctxt); yajl_free_error(yh, err); } else { if (error_func) error_func(yajl_get_bytes_consumed(yh), yajl_context.parser_ctxt.error, SchemaGetErrorMessage(yajl_context.parser_ctxt.error), error_ctxt); } yajl_free(yh); JsonSchemaParserFree(parser, free); return NULL; } // Let the parser finish its job. static TokenParam token_param; JsonSchemaParser(parser, 0, token_param, &yajl_context.parser_ctxt); // Even if parsing was completed there can be an error if (!yajl_context.parser_ctxt.error == SEC_OK) { if (error_func) error_func(yajl_get_bytes_consumed(yh), yajl_context.parser_ctxt.error, SchemaGetErrorMessage(yajl_context.parser_ctxt.error), error_ctxt); validator_unref(yajl_context.parser_ctxt.validator); yajl_free(yh); JsonSchemaParserFree(parser, free); return NULL; } yajl_free(yh); JsonSchemaParserFree(parser, free); // Post-parse processing Validator *v = yajl_context.parser_ctxt.validator; // Move parsed features to the validators validator_apply_features(v); // Combine type validator and other validators contaiters (allOf, anyOf, etc.) validator_combine(v); if (uri_resolver) validator_collect_uri(v, root_scope, uri_resolver); // Substitute every SchemaParsing by its type validator for every node // in the AST. Validator *result = validator_finalize_parse(v); // Forget about SchemaParsing then. validator_unref(v); return result; }
void additional_feature_set_validator(AdditionalFeature *a, Validator *v) { validator_unref(a->validator); a->validator = v; }
void schema_parsing_unref(SchemaParsing *s) { validator_unref(&s->base); }
static void _release_validator(gpointer data) { validator_unref((Validator *) data); }
void schema_parsing_set_extends(SchemaParsing *s, Validator *extends) { assert(s); validator_unref(s->extends); s->extends = extends; }