diff options
author | Alexander Barkov <bar@mariadb.com> | 2021-10-25 17:28:25 +0400 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-10-29 18:29:02 +0200 |
commit | 6bf5a3beb377d42d14c5cc68abd3e55aa05ee2db (patch) | |
tree | 460d4e9876e46f9855e2128f5ca7896dfa624fe7 | |
parent | 4300f50243f0c15766d39bf848374b6d44a7ef34 (diff) | |
download | mariadb-git-6bf5a3beb377d42d14c5cc68abd3e55aa05ee2db.tar.gz |
MDEV-26785 Hyphens inside the value of uuid datatype
-rw-r--r-- | plugin/type_uuid/mysql-test/type_uuid/type_uuid.result | 24 | ||||
-rw-r--r-- | plugin/type_uuid/mysql-test/type_uuid/type_uuid.test | 29 | ||||
-rw-r--r-- | plugin/type_uuid/sql_type_uuid.cc | 65 |
3 files changed, 102 insertions, 16 deletions
diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result index 615222651a5..77e718ca93c 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result @@ -3120,3 +3120,27 @@ SELECT MIN(a), MAX(a) FROM t1 GROUP BY id; MIN(a) MAX(a) 00000000-0000-0000-0000-000000000fff 00000000-0000-0000-0000-000000008888 DROP TABLE t1; +# +# MDEV-26785 Hyphens inside the value of uuid datatype +# +CREATE TABLE t1 (a UUID); +INSERT INTO t1 VALUES ('0000000000000000000000000000000'/*31 digits*/); +ERROR 22007: Incorrect uuid value: '0000000000000000000000000000000' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('000000000000000000000000000000000'/*33 digits*/); +ERROR 22007: Incorrect uuid value: '000000000000000000000000000000000' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('-00000000000000000000000000000000'/*leading hyphen*/); +ERROR 22007: Incorrect uuid value: '-00000000000000000000000000000000' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('-00000000000000000000000000000000-'/*trailing hyphen*/); +ERROR 22007: Incorrect uuid value: '-00000000000000000000000000000000-' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('00000000000000000000000000000000'); +INSERT INTO t1 VALUES ('0-0000000000000000000000000000011'); +INSERT INTO t1 VALUES ('0--0000000000000000000000000000012'); +INSERT INTO t1 VALUES ('0---0000000000000000000000000000013'); +INSERT INTO t1 VALUES ('0----0000000000000000000000000000014'); +INSERT INTO t1 VALUES ('00-000000000000000000000000000021'); +INSERT INTO t1 VALUES ('00--000000000000000000000000000022'); +INSERT INTO t1 VALUES ('00---000000000000000000000000000023'); +INSERT INTO t1 VALUES ('00----000000000000000000000000000024'); +INSERT INTO t1 VALUES ('5796dac11a1c11--------------ecab4ef859-713e4be4'); +INSERT INTO t1 VALUES ('5796dac11a1c11---------------ecab4ef859-713e4be4'); +DROP TABLE t1; diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.test b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.test index 5f1ffc3e97c..c3c704ad29d 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.test +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.test @@ -1617,3 +1617,32 @@ INSERT INTO t1 VALUES (1, '00000000-0000-0000-0000-000000008888'); SELECT MIN(a), MAX(a) FROM t1 GROUP BY id; DROP TABLE t1; + + +--echo # +--echo # MDEV-26785 Hyphens inside the value of uuid datatype +--echo # + +CREATE TABLE t1 (a UUID); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('0000000000000000000000000000000'/*31 digits*/); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('000000000000000000000000000000000'/*33 digits*/); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('-00000000000000000000000000000000'/*leading hyphen*/); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('-00000000000000000000000000000000-'/*trailing hyphen*/); + +INSERT INTO t1 VALUES ('00000000000000000000000000000000'); +INSERT INTO t1 VALUES ('0-0000000000000000000000000000011'); +INSERT INTO t1 VALUES ('0--0000000000000000000000000000012'); +INSERT INTO t1 VALUES ('0---0000000000000000000000000000013'); +INSERT INTO t1 VALUES ('0----0000000000000000000000000000014'); +INSERT INTO t1 VALUES ('00-000000000000000000000000000021'); +INSERT INTO t1 VALUES ('00--000000000000000000000000000022'); +INSERT INTO t1 VALUES ('00---000000000000000000000000000023'); +INSERT INTO t1 VALUES ('00----000000000000000000000000000024'); + +INSERT INTO t1 VALUES ('5796dac11a1c11--------------ecab4ef859-713e4be4'); +INSERT INTO t1 VALUES ('5796dac11a1c11---------------ecab4ef859-713e4be4'); +DROP TABLE t1; diff --git a/plugin/type_uuid/sql_type_uuid.cc b/plugin/type_uuid/sql_type_uuid.cc index 412082cacbb..9b4a731dbb2 100644 --- a/plugin/type_uuid/sql_type_uuid.cc +++ b/plugin/type_uuid/sql_type_uuid.cc @@ -42,28 +42,61 @@ static bool get_digit(char ch, uint *val) } -bool UUID::ascii_to_fbt(const char *str, size_t str_length) +static bool get_digit(uint *val, const char *str, const char *end) { - if (str_length < 32 || str_length > 3 * binary_length() - 1) + if (str >= end) return true; + return get_digit(*str, val); +} + - uint oidx= 0; - for (const char *s= str; s < str + str_length; ) +static size_t skip_hyphens(const char *str, const char *end) +{ + const char *str0= str; + for ( ; str < end; str++) { - if (oidx >= binary_length()) - goto err; - if (*s == '-') - { - if (s == str) - goto err; - s++; - continue; - } - uint hi, lo; - if (get_digit(*s++, &hi) || get_digit(*s++, &lo)) + if (str[0] != '-') + break; + } + return str - str0; +} + + +static const char *get_two_digits(char *val, const char *str, const char *end) +{ + uint hi, lo; + if (get_digit(&hi, str++, end)) + return NULL; + str+= skip_hyphens(str, end); + if (get_digit(&lo, str++, end)) + return NULL; + *val= (char) ((hi << 4) + lo); + return str; +} + + +bool UUID::ascii_to_fbt(const char *str, size_t str_length) +{ + const char *end= str + str_length; + /* + The format understood: + - Hyphen is not allowed on the first and the last position. + - Otherwise, hyphens are allowed on any (odd and even) position, + with any amount. + */ + if (str_length < 32) + goto err; + + for (uint oidx= 0; oidx < binary_length(); oidx++) + { + if (!(str= get_two_digits(&m_buffer[oidx], str, end))) goto err; - m_buffer[oidx++]= (char) ((hi << 4) + lo); + // Allow hypheps after two digits, but not after the last digit + if (oidx + 1 < binary_length()) + str+= skip_hyphens(str, end); } + if (str < end) + goto err; // Some input left return false; err: bzero(m_buffer, sizeof(m_buffer)); |