From ee02650bac49b66a38c7c485ea2f81edd4403ffc Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Tue, 18 Aug 2015 12:24:27 +0530 Subject: [PATCH] Bug #16171518 - LOAD XML DOES NOT HANDLE EMPTY ELEMENTS DESCRIPTION =========== Inability of mysql LOAD XML command to handle empty XML tags i.e. . Also the behaviour is wrong and (different than above) when there is a space in empty tag i.e. ANALYSIS ======== In read_xml() the case where we encounter a close tag ('/') we're decreasing the 'level' blindly which is wrong. Actually when its an without-space-empty-tag (succeeding char is '>'), we need to skip the decrement. In other words whenever we hit a close tag ('/'), decrease the 'level' only when (i) It's not an (without space) empty tag i.e. or, (ii) It is of format FIX === The switch case for '/' is modified. We've removed the blind decrement of 'level'. We do it only when its not an without-space-empty-tag. Also we are setting 'in_tag' to false to let program know that we're done reading current tag (required in the case of format ) --- mysql-test/r/loadxml.result | 27 ++++++++++++ mysql-test/std_data/bug16171518_1.dat | 59 +++++++++++++++++++++++++++ mysql-test/std_data/bug16171518_2.dat | 12 ++++++ mysql-test/t/loadxml.test | 14 +++++++ sql/sql_load.cc | 11 ++++- 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 mysql-test/std_data/bug16171518_1.dat create mode 100644 mysql-test/std_data/bug16171518_2.dat diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result index 7742f456252..1128caf9122 100644 --- a/mysql-test/r/loadxml.result +++ b/mysql-test/r/loadxml.result @@ -93,3 +93,30 @@ a b 216 !&bb b; 3 !b3 DROP TABLE t1; +# +# Bug#16171518 LOAD XML DOES NOT HANDLE EMPTY ELEMENTS +# +CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 VARCHAR(3), col4 VARCHAR(4)); +LOAD XML INFILE '../../std_data/bug16171518_1.dat' INTO TABLE t1; +SELECT * FROM t1 ORDER BY col1, col2, col3, col4; +col1 col2 col3 col4 +0bc def ghi jkl +1no NULL pqr stu +2BC DEF GHI JKL +3NO NULL PQR STU +4bc def ghi jkl +5no pqr stu vwx +6BC DEF NULL JKL +7NO PQR STU VWX +8bc def ghi NULL +9kl NULL mno pqr +ABC DEF NULL JKL +MNO NULL STU VWX +DROP TABLE t1; +CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER); +LOAD XML INFILE '../../std_data/bug16171518_2.dat' INTO TABLE t1; +SELECT * FROM t1 ORDER BY col1, col2, col3; +col1 col2 col3 +ABC DEF NULL +GHI NULL 123 +DROP TABLE t1; diff --git a/mysql-test/std_data/bug16171518_1.dat b/mysql-test/std_data/bug16171518_1.dat new file mode 100644 index 00000000000..b65b9359ce1 --- /dev/null +++ b/mysql-test/std_data/bug16171518_1.dat @@ -0,0 +1,59 @@ + + + 0bc + def + ghi + jkl + + + 1no + + pqr + stu + + + + 2BC + DEF + GHI + JKL + + + 3NO + + PQR + STU + + + + + + + 6BC + DEF + + JKL + + + 7NO + PQR + STU + VWX + + + + 8bc + def + ghi + + + + 9kl + + mno + pqr + + + + + diff --git a/mysql-test/std_data/bug16171518_2.dat b/mysql-test/std_data/bug16171518_2.dat new file mode 100644 index 00000000000..8a483337a0f --- /dev/null +++ b/mysql-test/std_data/bug16171518_2.dat @@ -0,0 +1,12 @@ + + + ABC + DEF + + + + GHI + + 123 + + diff --git a/mysql-test/t/loadxml.test b/mysql-test/t/loadxml.test index 6faf712b6ce..93e6e82189f 100644 --- a/mysql-test/t/loadxml.test +++ b/mysql-test/t/loadxml.test @@ -116,3 +116,17 @@ LOAD XML INFILE '../../std_data/loadxml.dat' INTO TABLE t1 ROWS IDENTIFIED BY '' (a,@b) SET b=concat('!',@b); SELECT * FROM t1 ORDER BY a; DROP TABLE t1; + + +--echo # +--echo # Bug#16171518 LOAD XML DOES NOT HANDLE EMPTY ELEMENTS +--echo # +CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 VARCHAR(3), col4 VARCHAR(4)); +LOAD XML INFILE '../../std_data/bug16171518_1.dat' INTO TABLE t1; +SELECT * FROM t1 ORDER BY col1, col2, col3, col4; +DROP TABLE t1; + +CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER); +LOAD XML INFILE '../../std_data/bug16171518_2.dat' INTO TABLE t1; +SELECT * FROM t1 ORDER BY col1, col2, col3; +DROP TABLE t1; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 05571d49cc8..5f72d3ce520 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1987,8 +1987,15 @@ int READ_INFO::read_xml() break; case '/': /* close tag */ - level--; chr= my_tospace(GET); + /* Decrease the 'level' only when (i) It's not an */ + /* (without space) empty tag i.e. or, (ii) */ + /* It is of format */ + if(chr != '>' || in_tag) + { + level--; + in_tag= false; + } if(chr != '>') /* if this is an empty tag */ tag.length(0); /* we should keep tag value */ while(chr != '>' && chr != my_b_EOF)