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.
This commit is contained in:
parent
d555f38af8
commit
dffd1679ba
@ -4590,4 +4590,19 @@ JSON_SCHEMA_VALID(@invalid_schema, '{"number1":3, "obj2":{"key1":3}}')
|
|||||||
NULL
|
NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_schema_valid' at position 45
|
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
|
# End of 11.1 test
|
||||||
|
@ -3357,6 +3357,7 @@ SET @schema_reference= '{"$defs": "http://example.com/custom-email-validator.jso
|
|||||||
SELECT JSON_SCHEMA_VALID(@schema_reference, '{}');
|
SELECT JSON_SCHEMA_VALID(@schema_reference, '{}');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment
|
--echo # MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment
|
||||||
--echo #
|
--echo #
|
||||||
@ -3474,4 +3475,23 @@ SET @invalid_schema= '{"type":"object"
|
|||||||
}';
|
}';
|
||||||
SELECT JSON_SCHEMA_VALID(@invalid_schema, '{"number1":3, "obj2":{"key1":3}}');
|
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
|
--echo # End of 11.1 test
|
||||||
|
@ -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_NUMBER)
|
||||||
{
|
{
|
||||||
if (temp_je.value_type == JSON_VALUE_TRUE)
|
if (!(enum_scalar & (1 << temp_je.value_type)))
|
||||||
return !(enum_scalar & HAS_TRUE_VAL);
|
return true;
|
||||||
if (temp_je.value_type == JSON_VALUE_FALSE)
|
else
|
||||||
return !(enum_scalar & HAS_FALSE_VAL);
|
return false;
|
||||||
if (temp_je.value_type == JSON_VALUE_NULL)
|
|
||||||
return !(enum_scalar & HAS_NULL_VAL);
|
|
||||||
}
|
}
|
||||||
json_get_normalized_string(&temp_je, &a_res, &err);
|
json_get_normalized_string(&temp_je, &a_res, &err);
|
||||||
if (err)
|
if (err)
|
||||||
@ -546,6 +544,7 @@ bool Json_schema_enum::handle_keyword(THD *thd, json_engine_t *je,
|
|||||||
List<Json_schema_keyword>
|
List<Json_schema_keyword>
|
||||||
*all_keywords)
|
*all_keywords)
|
||||||
{
|
{
|
||||||
|
int count= 0;
|
||||||
if (my_hash_init(PSI_INSTRUMENT_ME,
|
if (my_hash_init(PSI_INSTRUMENT_ME,
|
||||||
&this->enum_values,
|
&this->enum_values,
|
||||||
je->s.cs, 1024, 0, 0, (my_hash_get_key) get_key_name,
|
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))
|
if (json_read_value(je))
|
||||||
return true;
|
return true;
|
||||||
|
count++;
|
||||||
if (je->value_type > JSON_VALUE_NUMBER)
|
if (je->value_type > JSON_VALUE_NUMBER)
|
||||||
{
|
{
|
||||||
if (je->value_type == JSON_VALUE_TRUE)
|
if (!(enum_scalar & (1 << je->value_type)))
|
||||||
enum_scalar|= HAS_TRUE_VAL;
|
enum_scalar|= 1 << je->value_type;
|
||||||
else if (je->value_type == JSON_VALUE_FALSE)
|
else
|
||||||
enum_scalar|= HAS_FALSE_VAL;
|
{
|
||||||
else if (je->value_type == JSON_VALUE_NULL)
|
my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "enum");
|
||||||
enum_scalar|= HAS_NULL_VAL;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -586,12 +587,26 @@ bool Json_schema_enum::handle_keyword(THD *thd, json_engine_t *je,
|
|||||||
{
|
{
|
||||||
norm_str[a_res.length()]= '\0';
|
norm_str[a_res.length()]= '\0';
|
||||||
strncpy(norm_str, (const char*)a_res.ptr(), a_res.length());
|
strncpy(norm_str, (const char*)a_res.ptr(), a_res.length());
|
||||||
|
if (!my_hash_search(&this->enum_values, (uchar*)norm_str,
|
||||||
|
strlen(norm_str)))
|
||||||
|
{
|
||||||
if (my_hash_insert(&this->enum_values, (uchar*)norm_str))
|
if (my_hash_insert(&this->enum_values, (uchar*)norm_str))
|
||||||
return true;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -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
|
class Json_schema_enum : public Json_schema_keyword
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -196,7 +193,7 @@ class Json_schema_enum : public Json_schema_keyword
|
|||||||
List<Json_schema_keyword> *all_keywords) override;
|
List<Json_schema_keyword> *all_keywords) override;
|
||||||
Json_schema_enum()
|
Json_schema_enum()
|
||||||
{
|
{
|
||||||
enum_scalar= HAS_NO_VAL;
|
enum_scalar= 0;
|
||||||
}
|
}
|
||||||
~Json_schema_enum()
|
~Json_schema_enum()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user