diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2021-03-23 13:23:37 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2021-04-21 10:21:44 +0400 |
commit | 46d592a047a6a9a062e07fe511a6164fd5ccfc22 (patch) | |
tree | 4ed63ef77a600cf81de77c5c9df568bfab4e0ab2 | |
parent | 0eda81e4d964898db271e08a68ef9ea1760913e0 (diff) | |
download | mariadb-git-46d592a047a6a9a062e07fe511a6164fd5ccfc22.tar.gz |
MDEV-25188 JSON_TABLE: ASAN use-after-poison in Field_long::reset / Table_function_json_table::setup or malloc(): invalid size.
MDEV-25192 JSON_TABLE: ASAN use-after-poison in field_conv_memcpy / Create_tmp_table::finalize upon query with derived table.
-rw-r--r-- | mysql-test/suite/json/r/json_table.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/json/t/json_table.test | 12 | ||||
-rw-r--r-- | sql/field.h | 15 | ||||
-rw-r--r-- | sql/json_table.cc | 22 |
4 files changed, 43 insertions, 20 deletions
diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 991884c9f74..aa3e56f62db 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -522,5 +522,19 @@ SELECT * FROM JSON_TABLE('{}', '$' COLUMNS(a CHAR(100) PATH '$' DEFAULT "0" ON E a 0 # +# MDEV-25188 JSON_TABLE: ASAN use-after-poison in Field_long::reset / Table_function_json_table::setup or malloc(): invalid size. +# +SELECT * FROM JSON_TABLE(CONVERT('{"x":1}' USING utf8mb4), '$' COLUMNS(a INT PATH '$', b CHAR(64) PATH '$.*', c INT EXISTS PATH '$**.*')) AS jt; +a b c +NULL 1 1 +# +# 25192 JSON_TABLE: ASAN use-after-poison in field_conv_memcpy / Create_tmp_table::finalize upon query with derived table. +# +SET NAMES utf8; +SELECT * FROM ( SELECT * FROM JSON_TABLE('{}', '$' COLUMNS( a BINARY(12) PATH '$.*', b VARCHAR(40) PATH '$[*]', c VARCHAR(8) PATH '$**.*')) AS jt ) AS sq; +a b c +NULL NULL NULL +SET NAMES default; +# # End of 10.6 tests # diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index 29e9f0e8764..fd6835011ef 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -401,5 +401,17 @@ DROP VIEW v; SELECT * FROM JSON_TABLE('{}', '$' COLUMNS(a CHAR(100) PATH '$' DEFAULT "0" ON ERROR)) AS jt; --echo # +--echo # MDEV-25188 JSON_TABLE: ASAN use-after-poison in Field_long::reset / Table_function_json_table::setup or malloc(): invalid size. +--echo # +SELECT * FROM JSON_TABLE(CONVERT('{"x":1}' USING utf8mb4), '$' COLUMNS(a INT PATH '$', b CHAR(64) PATH '$.*', c INT EXISTS PATH '$**.*')) AS jt; + +--echo # +--echo # 25192 JSON_TABLE: ASAN use-after-poison in field_conv_memcpy / Create_tmp_table::finalize upon query with derived table. +--echo # +SET NAMES utf8; +SELECT * FROM ( SELECT * FROM JSON_TABLE('{}', '$' COLUMNS( a BINARY(12) PATH '$.*', b VARCHAR(40) PATH '$[*]', c VARCHAR(8) PATH '$**.*')) AS jt ) AS sq; +SET NAMES default; + +--echo # --echo # End of 10.6 tests --echo # diff --git a/sql/field.h b/sql/field.h index 557b0aaffa4..b312b10881f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1612,7 +1612,7 @@ public: virtual const TYPELIB *get_typelib() const { return NULL; } virtual CHARSET_INFO *charset() const= 0; /* returns TRUE if the new charset differs. */ - virtual bool change_charset(const DTCollation &new_cs) { return FALSE; } + virtual void change_charset(const DTCollation &new_cs) {} virtual const DTCollation &dtcollation() const= 0; virtual CHARSET_INFO *charset_for_protocol(void) const { return binary() ? &my_charset_bin : charset(); } @@ -2111,16 +2111,11 @@ public: { return m_collation; } - bool change_charset(const DTCollation &new_cs) override + void change_charset(const DTCollation &new_cs) override { - if (m_collation.collation != new_cs.collation) - { - field_length= (field_length * new_cs.collation->mbmaxlen) / - m_collation.collation->mbmaxlen; - m_collation= new_cs; - return TRUE; - } - return FALSE; + field_length= (field_length * new_cs.collation->mbmaxlen) / + m_collation.collation->mbmaxlen; + m_collation= new_cs; } bool binary() const override { return field_charset() == &my_charset_bin; } uint32 max_display_length() const override { return field_length; } diff --git a/sql/json_table.cc b/sql/json_table.cc index 7fb7ce969e5..6f6c270137a 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -718,7 +718,10 @@ bool Create_json_table::finalize(THD *thd, TABLE *table, m_null_count & 7); m_null_count+= (field->field_length & 7); } - field->reset(); + /* + Here we'd call the field->reset(), but we're doing it later + in Table_function_json_table::setup as we define charsets there. + */ /* Test if there is a default field value. The test for ->ptr is to skip @@ -811,7 +814,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table, */ sql_f->length= sql_f->char_length; if (!(jc->m_explicit_cs= sql_f->charset)) - sql_f->charset= &my_charset_utf8mb4_bin; + sql_f->charset= &my_charset_utf8mb4_general_ci; if (sql_f->prepare_stage1(thd, thd->mem_root, table->file, table->file->ha_table_flags())) @@ -1148,14 +1151,13 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table, Json_table_column *jc= jc_i++; uint32 old_pack_length= f->pack_length(); - if (f->change_charset( - jc->m_explicit_cs ? jc->m_explicit_cs : m_json->collation) || - field_offset) - { - if (field_offset) - f->move_field(f->ptr + field_offset, f->null_ptr, f->null_bit); - f->reset(); - } + f->change_charset( + jc->m_explicit_cs ? jc->m_explicit_cs : m_json->collation); + + if (field_offset) + f->move_field(f->ptr + field_offset, f->null_ptr, f->null_bit); + + f->reset(); field_offset= (field_offset + f->pack_length()) - old_pack_length; |