MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value

always return 1

Analysis: Implementation used double to store value. longlong is better
choice
Fix: Use longlong for multiple_of and the value to store it and num_flag to
check for decimals.
This commit is contained in:
Rucha Deodhar 2023-03-03 13:50:46 +05:30
parent 2c4c7c8b02
commit 4b67ff3b25
4 changed files with 44 additions and 8 deletions

View file

@ -4634,4 +4634,19 @@ ERROR HY000: Invalid value for keyword maxLength
SET @schema= '{ "items" : ["str1"]}';
SELECT JSON_SCHEMA_VALID(@schema, '[]');
ERROR HY000: Invalid value for keyword items
#
# MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value always return 1
#
SET @schema = '{
"multipleOf": 2
}';
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000001');
JSON_SCHEMA_VALID(@schema, '9007900000000001')
0
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000060');
JSON_SCHEMA_VALID(@schema, '9007900000000060')
1
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000061');
JSON_SCHEMA_VALID(@schema, '9007900000000061')
0
# End of 11.1 test

View file

@ -3533,4 +3533,15 @@ SET @schema= '{ "items" : ["str1"]}';
SELECT JSON_SCHEMA_VALID(@schema, '[]');
--echo #
--echo # MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value always return 1
--echo #
SET @schema = '{
"multipleOf": 2
}';
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000001');
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000060');
SELECT JSON_SCHEMA_VALID(@schema, '9007900000000061');
--echo # End of 11.1 test

View file

@ -771,13 +771,25 @@ bool Json_schema_multiple_of::validate(const json_engine_t *je,
if (je->value_type != JSON_VALUE_NUMBER)
return false;
if (je->num_flags & JSON_NUM_FRAC_PART)
return true;
<<<<<<< HEAD
double val= je->s.cs->strntod((char *) je->value,
je->value_len, &end, &err);
double temp= val / multiple_of;
bool res= (temp - (long long int)temp) == 0;
||||||| parent of 628ce9d4f44... MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value
double val= je->s.cs->strntod((char *) je->value,
je->value_len, &end, &err);
double temp= val / this->value;
bool res= (temp - (long long int)temp) == 0;
=======
longlong val= je->s.cs->strntoll((char *) je->value,
je->value_len, 10, &end, &err);
>>>>>>> 628ce9d4f44... MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value
return !res;
return val % multiple_of;
}
bool Json_schema_multiple_of::handle_keyword(THD *thd, json_engine_t *je,
@ -789,19 +801,16 @@ bool Json_schema_multiple_of::handle_keyword(THD *thd, json_engine_t *je,
int err= 0;
char *end;
if (je->value_type != JSON_VALUE_NUMBER)
if (je->value_type != JSON_VALUE_NUMBER || (je->num_flags & JSON_NUM_FRAC_PART))
{
my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "multipleOf");
return true;
}
double val= je->s.cs->strntod((char *) je->value,
je->value_len, &end, &err);
longlong val= je->s.cs->strntoll((char *) je->value,
je->value_len, 10, &end, &err);
if (val <= 0)
{
my_error(ER_JSON_INVALID_VALUE_FOR_KEYWORD, MYF(0), "multipleOf");
return true;
}
multiple_of= val;
return false;

View file

@ -228,7 +228,8 @@ class Json_schema_minimum : public Json_schema_keyword
class Json_schema_multiple_of : public Json_schema_keyword
{
private:
double multiple_of;
longlong multiple_of;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
const uchar *k_end= NULL) override;