diff options
-rw-r--r-- | mysql-test/main/func_json.result | 34 | ||||
-rw-r--r-- | mysql-test/main/func_json.test | 42 | ||||
-rw-r--r-- | sql/json_schema.cc | 28 |
3 files changed, 102 insertions, 2 deletions
diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 8b2b30cea8f..dddfcf8f1cd 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -4462,4 +4462,38 @@ ERROR HY000: $anchor keyword is not supported SET @schema_reference= '{"$defs": "http://example.com/custom-email-validator.json#"}'; SELECT JSON_SCHEMA_VALID(@schema_reference, '{}'); ERROR HY000: $defs keyword is not supported +# +# MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment +# +SET @schema= '{ + "type":"array", + "uniqueItems":true + }'; +SELECT JSON_SCHEMA_VALID(@schema, '[null, null]'); +JSON_SCHEMA_VALID(@schema, '[null, null]') +0 +SET @schema_max_items= '{"maxItems":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_max_items, '[]'); +ERROR HY000: Invalid value for keyword maxItems +SET @schema_min_items= '{"minItems":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_min_items, '[]'); +ERROR HY000: Invalid value for keyword maxLength +SET @schema_max_properties= '{"maxProperties":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_max_properties, '{}'); +ERROR HY000: Invalid value for keyword maxProperties +SET @schema_min_properties= '{"minProperties":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_min_properties, '{}'); +ERROR HY000: Invalid value for keyword minProperties +SET @schema_multiple_of= '{"multipleOf":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_multiple_of, '2'); +ERROR HY000: Invalid value for keyword multipleOf +SET @schema_max_contains= '{"maxContains":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_max_contains, '[]'); +ERROR HY000: Invalid value for keyword maxContains +SET @schema_min_contains= '{"minContains":-1}'; +SELECT JSON_SCHEMA_VALID(@schema_min_contains, '[]'); +ERROR HY000: Invalid value for keyword minContains +SET @schema_required='{"type":"object","required":[1,"str1", "str1"]}'; +SELECT JSON_SCHEMA_VALID(@schema_required,'{"num1":1, "str1":"abc", "arr1":[1,2,3]}'); +ERROR HY000: Invalid value for keyword required # End of 11.1 test diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 7836a1f32ec..706a01d4528 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -3357,4 +3357,46 @@ SET @schema_reference= '{"$defs": "http://example.com/custom-email-validator.jso SELECT JSON_SCHEMA_VALID(@schema_reference, '{}'); +--echo # +--echo # MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment +--echo # +SET @schema= '{ + "type":"array", + "uniqueItems":true + }'; +SELECT JSON_SCHEMA_VALID(@schema, '[null, null]'); + +SET @schema_max_items= '{"maxItems":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_max_items, '[]'); + +SET @schema_min_items= '{"minItems":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_min_items, '[]'); + +SET @schema_max_properties= '{"maxProperties":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_max_properties, '{}'); + +SET @schema_min_properties= '{"minProperties":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_min_properties, '{}'); + +SET @schema_multiple_of= '{"multipleOf":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_multiple_of, '2'); + +SET @schema_max_contains= '{"maxContains":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_max_contains, '[]'); + +SET @schema_min_contains= '{"minContains":-1}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_min_contains, '[]'); + +SET @schema_required='{"type":"object","required":[1,"str1", "str1"]}'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema_required,'{"num1":1, "str1":"abc", "arr1":[1,2,3]}'); + + --echo # End of 11.1 test diff --git a/sql/json_schema.cc b/sql/json_schema.cc index b4b2e24d644..2279bb59f9a 100644 --- a/sql/json_schema.cc +++ b/sql/json_schema.cc @@ -783,7 +783,10 @@ bool Json_schema_multiple_of::handle_keyword(THD *thd, json_engine_t *je, double val= je->s.cs->strntod((char *) je->value, je->value_len, &end, &err); if (val < 0) + { my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "multipleOf"); + return true; + } value= val; return false; @@ -849,7 +852,10 @@ bool Json_schema_min_len::handle_keyword(THD *thd, json_engine_t *je, double val= je->s.cs->strntod((char *) je->value, je->value_len, &end, &err); if (val < 0) + { my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "minLength"); + return true; + } value= val; return false; @@ -1038,6 +1044,11 @@ bool Json_schema_max_contains::handle_keyword(THD *thd, json_engine_t *je, double val= je->s.cs->strntod((char *) je->value, je->value_len, &end, &err); + if (val < 0) + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "maxContains"); + return true; + } value= val; return false; } @@ -1061,6 +1072,12 @@ bool Json_schema_min_contains::handle_keyword(THD *thd, json_engine_t *je, double val= je->s.cs->strntod((char *) je->value, je->value_len, &end, &err); value= val; + if (val < 0) + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "minContains"); + return true; + } + return false; } @@ -1280,7 +1297,7 @@ bool Json_schema_unique_items::validate(const json_engine_t *je, HASH unique_items; List <char> norm_str_list; json_engine_t curr_je= *je; - int res= true, level= curr_je.stack_p; + int res= true, level= curr_je.stack_p, scalar_val= 0; if (curr_je.value_type != JSON_VALUE_ARRAY) return false; @@ -1291,7 +1308,7 @@ bool Json_schema_unique_items::validate(const json_engine_t *je, while(json_scan_next(&curr_je)==0 && level <= curr_je.stack_p) { - int scalar_val= 0, err= 1; + int err= 1; char *norm_str; String a_res("", 0, curr_je.s.cs); @@ -1330,7 +1347,9 @@ bool Json_schema_unique_items::validate(const json_engine_t *je, } a_res.set("", 0, curr_je.s.cs); } + res= false; + end: if (!norm_str_list.is_empty()) { @@ -1563,6 +1582,11 @@ bool Json_schema_required::handle_keyword(THD *thd, json_engine_t *je, { if (json_read_value(je)) return true; + if (je->value_type != JSON_VALUE_STRING) + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "required"); + return true; + } else { String *str= new (thd->mem_root)String((char*)je->value, |