Skip to content

Commit 51ac57f

Browse files
author
Alexey Botchkov
committed
MDEV-25151 JSON_TABLE: Unexpectedly padded values in a PATH column.
Field length can increase after the change_charset(), so need to set field->ptr properly. also sensitive parts of the test moved to json_not_embedded.test.
1 parent 047eb22 commit 51ac57f

File tree

5 files changed

+90
-51
lines changed

5 files changed

+90
-51
lines changed

mysql-test/suite/json/r/json_table.result

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,6 @@ a
9898
1
9999
connection default;
100100
disconnect con1;
101-
create database db;
102-
use db;
103-
create table t (a text);
104-
insert into t values ('{"foo":"bar"}');
105-
create user u@localhost;
106-
grant select (a) on db.t to u@localhost;
107-
connect con1,localhost,u,,db;
108-
select a from t;
109-
a
110-
{"foo":"bar"}
111-
select * from t, json_table(t.a, '$' columns(f varchar(20) path '$.foo')) as jt;
112-
a f
113-
{"foo":"bar"} bar
114-
select * into outfile 'f' from json_table('[]', '$' columns(x for ordinality)) q;
115-
ERROR 28000: Access denied for user 'u'@'localhost' (using password: NO)
116-
connection default;
117-
disconnect con1;
118-
drop user u@localhost;
119-
drop database db;
120-
use test;
121101
create table t1 (
122102
color varchar(32),
123103
price int
@@ -515,5 +495,15 @@ a
515495
SELECT a, b FROM JSON_TABLE('[]', '$' COLUMNS (a FOR ORDINALITY, b INT PATH '$[*]' ERROR ON EMPTY)) AS t ORDER BY a;
516496
ERROR HY000: Field 'b' can't be set for JSON_TABLE 't'.
517497
#
498+
# MDEV-25151 JSON_TABLE: Unexpectedly padded values in a PATH column.
499+
#
500+
SET @old_character_set_connection= @@character_set_connection;
501+
SET @@character_set_connection= utf8;
502+
select hex(a), b from json_table('["foo","bar"]','$[*]' columns (a char(3) path '$', b for ordinality)) t;
503+
hex(a) b
504+
666F6F 1
505+
626172 2
506+
SET @@character_set_connection= @old_character_set_connection;
507+
#
518508
# End of 10.6 tests
519509
#
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
create database db;
2+
use db;
3+
create table t (a text);
4+
insert into t values ('{"foo":"bar"}');
5+
create user u@localhost;
6+
grant select (a) on db.t to u@localhost;
7+
connect con1,localhost,u,,db;
8+
select a from t;
9+
a
10+
{"foo":"bar"}
11+
select * from t, json_table(t.a, '$' columns(f varchar(20) path '$.foo')) as jt;
12+
a f
13+
{"foo":"bar"} bar
14+
select * into outfile 'f' from json_table('[]', '$' columns(x for ordinality)) q;
15+
ERROR 28000: Access denied for user 'u'@'localhost' (using password: NO)
16+
connection default;
17+
disconnect con1;
18+
drop user u@localhost;
19+
drop database db;
20+
use test;

mysql-test/suite/json/t/json_table.test

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,34 +59,6 @@ select a from json_table('{"a":0}',"$" columns(a for ordinality)) foo;
5959
connection default;
6060
disconnect con1;
6161

62-
#
63-
# MDEV-22302 JSON_TABLE: Column privilege is insufficient for query with json_table
64-
#
65-
66-
create database db;
67-
use db;
68-
create table t (a text);
69-
insert into t values ('{"foo":"bar"}');
70-
create user u@localhost;
71-
grant select (a) on db.t to u@localhost;
72-
73-
--connect (con1,localhost,u,,db)
74-
select a from t;
75-
select * from t, json_table(t.a, '$' columns(f varchar(20) path '$.foo')) as jt;
76-
77-
#
78-
# MDEV-25141 JSON_TABLE: SELECT into outfile bypasses file privilege check
79-
#
80-
--error ER_ACCESS_DENIED_ERROR
81-
select * into outfile 'f' from json_table('[]', '$' columns(x for ordinality)) q;
82-
83-
connection default;
84-
disconnect con1;
85-
86-
drop user u@localhost;
87-
drop database db;
88-
89-
use test;
9062
create table t1 (
9163
color varchar(32),
9264
price int
@@ -407,6 +379,14 @@ EXECUTE stmt;
407379
--error ER_JSON_TABLE_ERROR_ON_FIELD
408380
SELECT a, b FROM JSON_TABLE('[]', '$' COLUMNS (a FOR ORDINALITY, b INT PATH '$[*]' ERROR ON EMPTY)) AS t ORDER BY a;
409381

382+
--echo #
383+
--echo # MDEV-25151 JSON_TABLE: Unexpectedly padded values in a PATH column.
384+
--echo #
385+
SET @old_character_set_connection= @@character_set_connection;
386+
SET @@character_set_connection= utf8;
387+
select hex(a), b from json_table('["foo","bar"]','$[*]' columns (a char(3) path '$', b for ordinality)) t;
388+
SET @@character_set_connection= @old_character_set_connection;
389+
410390
--echo #
411391
--echo # End of 10.6 tests
412392
--echo #
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
source include/not_embedded.inc;
2+
3+
#
4+
# MDEV-22302 JSON_TABLE: Column privilege is insufficient for query with json_table
5+
#
6+
7+
create database db;
8+
use db;
9+
create table t (a text);
10+
insert into t values ('{"foo":"bar"}');
11+
create user u@localhost;
12+
grant select (a) on db.t to u@localhost;
13+
14+
--connect (con1,localhost,u,,db)
15+
select a from t;
16+
select * from t, json_table(t.a, '$' columns(f varchar(20) path '$.foo')) as jt;
17+
18+
#
19+
# MDEV-25141 JSON_TABLE: SELECT into outfile bypasses file privilege check
20+
#
21+
--error ER_ACCESS_DENIED_ERROR
22+
select * into outfile 'f' from json_table('[]', '$' columns(x for ordinality)) q;
23+
24+
connection default;
25+
disconnect con1;
26+
27+
drop user u@localhost;
28+
drop database db;
29+
30+
use test;

sql/json_table.cc

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,12 +1134,31 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
11341134
}
11351135

11361136
{
1137+
/*
1138+
The m_json defines it's charset during the fix_fields stage so we're
1139+
changing the field's current charsets with it.
1140+
The complicated part is that the length of the field can be changed so
1141+
in this case we should move all the consequent fiedlds.
1142+
*/
11371143
List_iterator_fast<Json_table_column> jc_i(m_columns);
1138-
for (uint i= 0; t->field[i]; i++)
1144+
int field_offset= 0;
1145+
Field *f;
1146+
for (uint i= 0; (f= t->field[i]); i++)
11391147
{
11401148
Json_table_column *jc= jc_i++;
1141-
t->field[i]->change_charset(
1142-
jc->m_explicit_cs ? jc->m_explicit_cs : m_json->collation);
1149+
uint32 old_pack_length= f->pack_length();
1150+
1151+
f->change_charset(
1152+
jc->m_explicit_cs ? jc->m_explicit_cs : m_json->collation);
1153+
1154+
if (field_offset)
1155+
{
1156+
f->move_field(f->ptr + field_offset, f->null_ptr, f->null_bit);
1157+
f->reset();
1158+
}
1159+
1160+
field_offset= (field_offset + f->pack_length()) - old_pack_length;
1161+
11431162
/*
11441163
The m_field->charset is going to be reused if it's the prepared
11451164
statement running several times. So should restored the original

0 commit comments

Comments
 (0)