From: Martin Hansson Date: December 22 2010 10:56am Subject: bzr commit into mysql-5.1-bugteam branch (martin.hansson:3525) Bug#58165 List-Archive: http://lists.mysql.com/commits/127496 X-Bug: 58165 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0011300944==" --===============0011300944== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///data0/martin/bzrroot/bug58165/5.1bt-lazy_copy/ based on revid:gleb.shchepa@stripped 3525 Martin Hansson 2010-12-22 Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail and other crashes The string manipulating SQL function insert() used a shared string buffer intended to contain an immutable empty string causing errors. With our code base this design faced two obstacles. The implementations of string valued SQL functions return pointers to String objects rather than the objects themselves and even if this were rectified we still have no protection against manipulation of shared string buffers. Fixed by always allocating a new String object whenever a function returns an empty string. Relevant code has also been documented. modified: mysql-test/r/func_str.result mysql-test/t/func_str.test sql/item_strfunc.cc sql/sql_string.cc === modified file 'mysql-test/r/func_str.result' --- a/mysql-test/r/func_str.result 2010-12-14 16:08:25 +0000 +++ b/mysql-test/r/func_str.result 2010-12-22 10:56:54 +0000 @@ -2612,4 +2612,20 @@ CONVERT(('' IN (REVERSE(CAST(('') AS DEC 1 Warnings: Warning 1292 Truncated incorrect DECIMAL value: '' +# +# Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail +# and other crashes +# +CREATE TABLE t1 ( a TEXT ); +SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt'; +SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' ); +insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' ) +x +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'b' +LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1; +SELECT * FROM t1; +a +aaaaaaaaaaaaaa +DROP TABLE t1; End of 5.1 tests === modified file 'mysql-test/t/func_str.test' --- a/mysql-test/t/func_str.test 2010-12-14 16:08:25 +0000 +++ b/mysql-test/t/func_str.test 2010-12-22 10:56:54 +0000 @@ -1369,4 +1369,15 @@ DROP TABLE t1; SELECT '1' IN ('1', SUBSTRING(-9223372036854775809, 1)); SELECT CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3)); +--echo # +--echo # Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail +--echo # and other crashes +--echo # +CREATE TABLE t1 ( a TEXT ); +SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt'; +SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' ); +LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + --echo End of 5.1 tests === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2010-10-12 19:28:03 +0000 +++ b/sql/item_strfunc.cc 2010-12-22 10:56:54 +0000 @@ -1299,8 +1299,12 @@ String *Item_func_substr_index::val_str( null_value=0; uint delimiter_length= delimiter->length(); if (!res->length() || !delimiter_length || !count) - return &my_empty_string; // Wrong parameters - + { + if (str->copy("", 1, default_charset_info)) // Wrong parameters + return str; + /* Out of memory */ + return NULL; + } res->set_charset(collation.collation); #ifdef USE_MB === modified file 'sql/sql_string.cc' --- a/sql/sql_string.cc 2010-07-09 12:00:17 +0000 +++ b/sql/sql_string.cc 2010-12-22 10:56:54 +0000 @@ -58,11 +58,28 @@ bool String::real_alloc(uint32 arg_lengt } -/* -** Check that string is big enough. Set string[alloc_length] to 0 -** (for C functions) -*/ +/** + Allocates a new buffer on the heap for this String. + + - If the String's internal buffer is privately owned and heap allocated, a + new buffer will be allocated, data moved and the old buffer freed. + - If the String does not keep a private buffer on the heap, such a buffer + will be allocated and the string copied accoring to its length, as found + in String::length(). + + For C compatibility, the new string buffer is null terminated. + + @param alloc_length The size of new buffer to be allocated, excluding null + terminator. If the current string buffer is larger than this value, no + allocation occurs. + + @retval false Either the copy operation is complete or, if the size of the + new buffer is smaller than the currently allocated buffer (if one exists), + no allocation occured. + + @retval true An error occured when attempting to allocate memory. +*/ bool String::realloc(uint32 alloc_length) { uint32 len=ALIGN_SIZE(alloc_length+1); @@ -196,6 +213,17 @@ bool String::copy() return FALSE; } +/** + Copies the internal buffer from str. If this String has a private heap + allocated buffer where new data does not fit, a new buffer is allocated + before copying and the old buffer freed. Character set information is also + copied. + + @param str The string whose internal buffer was duplicated. + + @retval false Success. + @retval true Memory allocation failed. + */ bool String::copy(const String &str) { if (alloc(str.str_length)) --===============0011300944== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/martin.hansson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: martin.hansson@stripped\ # pnqf48v0zjtt1udr # target_branch: file:///data0/martin/bzrroot/bug58165/5.1bt-\ # lazy_copy/ # testament_sha1: e54c50938e0103e22a4cde73ee865158cd8c3e7a # timestamp: 2010-12-22 11:56:58 +0100 # base_revision_id: gleb.shchepa@stripped\ # zmp7zt8io3j83oi0 # # Begin bundle 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 b/LyOtbzro2KxdyRThQkGJo94UA= --===============0011300944==--