summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2021-10-25 17:28:25 +0400
committerSergei Golubchik <serg@mariadb.org>2021-10-29 18:29:02 +0200
commit6bf5a3beb377d42d14c5cc68abd3e55aa05ee2db (patch)
tree460d4e9876e46f9855e2128f5ca7896dfa624fe7
parent4300f50243f0c15766d39bf848374b6d44a7ef34 (diff)
downloadmariadb-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.result24
-rw-r--r--plugin/type_uuid/mysql-test/type_uuid/type_uuid.test29
-rw-r--r--plugin/type_uuid/sql_type_uuid.cc65
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));