summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRucha Deodhar <rucha.deodhar@mariadb.com>2023-03-06 18:00:04 +0530
committerRucha Deodhar <rucha.deodhar@mariadb.com>2023-04-26 11:00:08 +0530
commit8939e21dc53bcb076da6991fb5b6114abfb3ee37 (patch)
tree43cc3e6d77fa2b9585171a54aee7eeef791f7fae
parent358b8495f5ffb19a1a89574fd897261e8ff12938 (diff)
downloadmariadb-git-8939e21dc53bcb076da6991fb5b6114abfb3ee37.tar.gz
MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment
comment 2) Analysis: flag to check unique gets reset every time. Hence unique values cannot be correctly checked Fix: do not reset the flag that checks unique for null, true and false values. comment 3) Analysis: current implementation checks for appropriate value but does not return true. Fix: return true on error comment 4) Analysis: Current implementation did not check for value type for values inside required array. Fix: Check values inside required array
-rw-r--r--mysql-test/main/func_json.result34
-rw-r--r--mysql-test/main/func_json.test42
-rw-r--r--sql/json_schema.cc28
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,