Commit 90c4dff5 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-25178 JSON_TABLE: ASAN use-after-poison in my_fill_8bit...

MDEV-25178 JSON_TABLE: ASAN use-after-poison in my_fill_8bit Json_table_column::On_response::respond.

table record buffer size was smaller than required when the charset
changes.
parent 6f56458a
...@@ -516,5 +516,11 @@ a b ...@@ -516,5 +516,11 @@ a b
NULL NULL NULL NULL
DROP VIEW v; DROP VIEW v;
# #
# MDEV-25178 JSON_TABLE: ASAN use-after-poison in my_fill_8bit / Json_table_column::On_response::respond
#
SELECT * FROM JSON_TABLE('{}', '$' COLUMNS(a CHAR(100) PATH '$' DEFAULT "0" ON ERROR)) AS jt;
a
0
#
# End of 10.6 tests # End of 10.6 tests
# #
...@@ -395,6 +395,11 @@ SHOW CREATE VIEW v; ...@@ -395,6 +395,11 @@ SHOW CREATE VIEW v;
SELECT * FROM v; SELECT * FROM v;
DROP VIEW v; DROP VIEW v;
--echo #
--echo # MDEV-25178 JSON_TABLE: ASAN use-after-poison in my_fill_8bit / Json_table_column::On_response::respond
--echo #
SELECT * FROM JSON_TABLE('{}', '$' COLUMNS(a CHAR(100) PATH '$' DEFAULT "0" ON ERROR)) AS jt;
--echo # --echo #
--echo # End of 10.6 tests --echo # End of 10.6 tests
--echo # --echo #
...@@ -1611,7 +1611,8 @@ class Field: public Value_source ...@@ -1611,7 +1611,8 @@ class Field: public Value_source
virtual longlong val_time_packed(THD *thd); virtual longlong val_time_packed(THD *thd);
virtual const TYPELIB *get_typelib() const { return NULL; } virtual const TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset() const= 0; virtual CHARSET_INFO *charset() const= 0;
virtual void change_charset(const DTCollation &new_cs) {} /* returns TRUE if the new charset differs. */
virtual bool change_charset(const DTCollation &new_cs) { return FALSE; }
virtual const DTCollation &dtcollation() const= 0; virtual const DTCollation &dtcollation() const= 0;
virtual CHARSET_INFO *charset_for_protocol(void) const virtual CHARSET_INFO *charset_for_protocol(void) const
{ return binary() ? &my_charset_bin : charset(); } { return binary() ? &my_charset_bin : charset(); }
...@@ -2110,11 +2111,16 @@ class Field_str :public Field { ...@@ -2110,11 +2111,16 @@ class Field_str :public Field {
{ {
return m_collation; return m_collation;
} }
void change_charset(const DTCollation &new_cs) override bool change_charset(const DTCollation &new_cs) override
{ {
field_length= (field_length * new_cs.collation->mbmaxlen) / if (m_collation.collation != new_cs.collation)
m_collation.collation->mbmaxlen; {
m_collation= new_cs; field_length= (field_length * new_cs.collation->mbmaxlen) /
m_collation.collation->mbmaxlen;
m_collation= new_cs;
return TRUE;
}
return FALSE;
} }
bool binary() const override { return field_charset() == &my_charset_bin; } bool binary() const override { return field_charset() == &my_charset_bin; }
uint32 max_display_length() const override { return field_length; } uint32 max_display_length() const override { return field_length; }
......
...@@ -811,7 +811,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table, ...@@ -811,7 +811,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table,
*/ */
sql_f->length= sql_f->char_length; sql_f->length= sql_f->char_length;
if (!(jc->m_explicit_cs= sql_f->charset)) if (!(jc->m_explicit_cs= sql_f->charset))
sql_f->charset= thd->variables.collation_server; sql_f->charset= &my_charset_utf8mb4_bin;
if (sql_f->prepare_stage1(thd, thd->mem_root, table->file, if (sql_f->prepare_stage1(thd, thd->mem_root, table->file,
table->file->ha_table_flags())) table->file->ha_table_flags()))
...@@ -1148,12 +1148,12 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table, ...@@ -1148,12 +1148,12 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
Json_table_column *jc= jc_i++; Json_table_column *jc= jc_i++;
uint32 old_pack_length= f->pack_length(); uint32 old_pack_length= f->pack_length();
f->change_charset( if (f->change_charset(
jc->m_explicit_cs ? jc->m_explicit_cs : m_json->collation); 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); if (field_offset)
f->move_field(f->ptr + field_offset, f->null_ptr, f->null_bit);
f->reset(); f->reset();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment