diff options
author | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2023-03-02 19:09:45 +0530 |
---|---|---|
committer | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2023-04-26 11:00:09 +0530 |
commit | dffd1679ba97e5e8145575f0f11cb87553670c6f (patch) | |
tree | bb8ecb0ef138d0c2fdb90939e59bb0bb481a72b2 | |
parent | d555f38af819db8b051c4f754358041f146e83f4 (diff) | |
download | mariadb-git-dffd1679ba97e5e8145575f0f11cb87553670c6f.tar.gz |
MDEV-30703: JSON_SCHEMA_VALID : Enum array must have at least one value
Analysis: Current implementation does not check the number of elements in
the enum array and whether they are unique or not.
Fix: Add a counter that counts number of elements and before inserting the
element in the enum hash check whether it exists.
-rw-r--r-- | mysql-test/main/func_json.result | 15 | ||||
-rw-r--r-- | mysql-test/main/func_json.test | 20 | ||||
-rw-r--r-- | sql/json_schema.cc | 45 | ||||
-rw-r--r-- | sql/json_schema.h | 7 |
4 files changed, 67 insertions, 20 deletions
diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 8b4c98ae9fd..5fee9ce4c32 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -4590,4 +4590,19 @@ JSON_SCHEMA_VALID(@invalid_schema, '{"number1":3, "obj2":{"key1":3}}') NULL Warnings: Warning 4038 Syntax error in JSON text in argument 1 to function 'json_schema_valid' at position 45 +# +# MDEV-30703: JSON_SCHEMA_VALID : Enum array must have at least one value +# +SET @schema = '{ + "type":"array", + "enum": [] + }'; +SELECT JSON_SCHEMA_VALID(@schema, '2'); +ERROR HY000: Invalid value for keyword enum +SET @schema = '{ + "type":"number", + "enum": [2, 2] + }'; +SELECT JSON_SCHEMA_VALID(@schema, '2'); +ERROR HY000: Invalid value for keyword enum # End of 11.1 test diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index c417a8ea4f8..a1e52a0494c 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -3357,6 +3357,7 @@ 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 # @@ -3474,4 +3475,23 @@ SET @invalid_schema= '{"type":"object" }'; SELECT JSON_SCHEMA_VALID(@invalid_schema, '{"number1":3, "obj2":{"key1":3}}'); +--echo # +--echo # MDEV-30703: JSON_SCHEMA_VALID : Enum array must have at least one value +--echo # + +SET @schema = '{ + "type":"array", + "enum": [] + }'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema, '2'); + +SET @schema = '{ + "type":"number", + "enum": [2, 2] + }'; +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID(@schema, '2'); + + --echo # End of 11.1 test diff --git a/sql/json_schema.cc b/sql/json_schema.cc index a358ef735d0..d0bb162cefe 100644 --- a/sql/json_schema.cc +++ b/sql/json_schema.cc @@ -520,12 +520,10 @@ bool Json_schema_enum::validate(const json_engine_t *je, if (temp_je.value_type > JSON_VALUE_NUMBER) { - if (temp_je.value_type == JSON_VALUE_TRUE) - return !(enum_scalar & HAS_TRUE_VAL); - if (temp_je.value_type == JSON_VALUE_FALSE) - return !(enum_scalar & HAS_FALSE_VAL); - if (temp_je.value_type == JSON_VALUE_NULL) - return !(enum_scalar & HAS_NULL_VAL); + if (!(enum_scalar & (1 << temp_je.value_type))) + return true; + else + return false; } json_get_normalized_string(&temp_je, &a_res, &err); if (err) @@ -546,6 +544,7 @@ bool Json_schema_enum::handle_keyword(THD *thd, json_engine_t *je, List<Json_schema_keyword> *all_keywords) { + int count= 0; if (my_hash_init(PSI_INSTRUMENT_ME, &this->enum_values, je->s.cs, 1024, 0, 0, (my_hash_get_key) get_key_name, @@ -559,14 +558,16 @@ bool Json_schema_enum::handle_keyword(THD *thd, json_engine_t *je, { if (json_read_value(je)) return true; + count++; if (je->value_type > JSON_VALUE_NUMBER) { - if (je->value_type == JSON_VALUE_TRUE) - enum_scalar|= HAS_TRUE_VAL; - else if (je->value_type == JSON_VALUE_FALSE) - enum_scalar|= HAS_FALSE_VAL; - else if (je->value_type == JSON_VALUE_NULL) - enum_scalar|= HAS_NULL_VAL; + if (!(enum_scalar & (1 << je->value_type))) + enum_scalar|= 1 << je->value_type; + else + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "enum"); + return true; + } } else { @@ -586,12 +587,26 @@ bool Json_schema_enum::handle_keyword(THD *thd, json_engine_t *je, { norm_str[a_res.length()]= '\0'; strncpy(norm_str, (const char*)a_res.ptr(), a_res.length()); - if (my_hash_insert(&this->enum_values, (uchar*)norm_str)) - return true; + if (!my_hash_search(&this->enum_values, (uchar*)norm_str, + strlen(norm_str))) + { + if (my_hash_insert(&this->enum_values, (uchar*)norm_str)) + return true; + } + else + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "enum"); + return true; + } } } } - return je->s.error ? true : false; + if (!count) + { + my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "enum"); + return true; + } + return false; } else { diff --git a/sql/json_schema.h b/sql/json_schema.h index 5da2576d7c4..4f1e146c862 100644 --- a/sql/json_schema.h +++ b/sql/json_schema.h @@ -176,10 +176,7 @@ class Json_schema_const : public Json_schema_keyword } }; -enum enum_scalar_values { - HAS_NO_VAL= 0, HAS_TRUE_VAL= 2, - HAS_FALSE_VAL= 4, HAS_NULL_VAL= 8 - }; + class Json_schema_enum : public Json_schema_keyword { private: @@ -196,7 +193,7 @@ class Json_schema_enum : public Json_schema_keyword List<Json_schema_keyword> *all_keywords) override; Json_schema_enum() { - enum_scalar= HAS_NO_VAL; + enum_scalar= 0; } ~Json_schema_enum() { |