# HG changeset patch # User Ramesh Maddali # Date 1374045422 25200 # Node ID 70e041ba5b04b20b201a8b8f85b995b55a50b268 # Parent 54a3a004ee1d4c47553cc03f24e407811e56728d 15688738 problem in database/mysql diff -r 54a3a004ee1d -r 70e041ba5b04 components/mysql-5-1/mysql-51test.p5m --- a/components/mysql-5-1/mysql-51test.p5m Mon Jul 15 23:01:56 2013 -0700 +++ b/components/mysql-5-1/mysql-51test.p5m Wed Jul 17 00:17:02 2013 -0700 @@ -477,6 +477,7 @@ file path=usr/mysql/5.1/mysql-test/r/bool.result file path=usr/mysql/5.1/mysql-test/r/bootstrap.result file path=usr/mysql/5.1/mysql-test/r/bug46080.result +file path=usr/mysql/5.1/mysql-test/r/bug40980.result file path=usr/mysql/5.1/mysql-test/r/bulk_replace.result file path=usr/mysql/5.1/mysql-test/r/cache_innodb.result file path=usr/mysql/5.1/mysql-test/r/case.result @@ -3297,6 +3298,7 @@ file path=usr/mysql/5.1/mysql-test/t/bootstrap.test file path=usr/mysql/5.1/mysql-test/t/bug46080-master.opt file path=usr/mysql/5.1/mysql-test/t/bug46080.test +file path=usr/mysql/5.1/mysql-test/t/bug40980.test file path=usr/mysql/5.1/mysql-test/t/bulk_replace.test file path=usr/mysql/5.1/mysql-test/t/cache_innodb-master.opt file path=usr/mysql/5.1/mysql-test/t/cache_innodb.test diff -r 54a3a004ee1d -r 70e041ba5b04 components/mysql-5-1/patches/bug40980.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/mysql-5-1/patches/bug40980.patch Wed Jul 17 00:17:02 2013 -0700 @@ -0,0 +1,113 @@ +# Fixes Solaris bug #15688738 +# =========================== + +--- storage/myisam/mi_delete_table.c 2006-12-31 00:32:21 +0000 ++++ storage/myisam/mi_delete_table.c 2010-04-01 14:49:02 +0000 +@@ -19,6 +19,41 @@ + + #include "fulltext.h" + ++ ++/** ++ Remove MyISAM data/index file safely ++ ++ @details ++ If name is a symlink and file it is pointing to is not in ++ data directory, file is also removed. ++ ++ @param name file to remove ++ ++ @returns ++ 0 on success or my_errno on failure ++*/ ++ ++static int _mi_safe_delete_file(const char *name) ++{ ++ DBUG_ENTER("_mi_safe_delete_file"); ++ if (my_is_symlink(name) && (*myisam_test_invalid_symlink)(name)) ++ { ++ /* ++ Symlink is pointing to file in data directory. ++ Remove symlink, keep file. ++ */ ++ if (my_delete(name, MYF(MY_WME))) ++ DBUG_RETURN(my_errno); ++ } ++ else ++ { ++ if (my_delete_with_symlink(name, MYF(MY_WME))) ++ DBUG_RETURN(my_errno); ++ } ++ DBUG_RETURN(0); ++} ++ ++ + int mi_delete_table(const char *name) + { + char from[FN_REFLEN]; +@@ -58,12 +93,12 @@ int mi_delete_table(const char *name) + #endif /* USE_RAID */ + + fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); +- if (my_delete_with_symlink(from, MYF(MY_WME))) ++ if (_mi_safe_delete_file(from)) + DBUG_RETURN(my_errno); + fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); + #ifdef USE_RAID + if (raid_type) + DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0); + #endif +- DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0); ++ DBUG_RETURN(_mi_safe_delete_file(from)); + } + +--- mysql-test/r/bug40980.result 1970-01-01 01:00:00.000000000 +0100 ++++ mysql-test/r/bug40980.result 2013-06-20 21:42:12.280326900 +0200 +@@ -0,0 +1,14 @@ ++drop table if exists t1,t2,t7,t8,t9; ++drop database if exists mysqltest; ++# ++# BUG#40980 - Drop table can remove another MyISAM table's ++# data and index files ++# ++CREATE TABLE user(a INT) DATA DIRECTORY='MYSQL_TMP_DIR/mysql' ++ INDEX DIRECTORY='MYSQL_TMP_DIR/mysql'; ++FLUSH TABLE user; ++# Symlinking mysql database to tmpdir ++FLUSH TABLE mysql.user; ++DROP TABLE user; ++FLUSH TABLE mysql.user; ++SELECT * FROM mysql.user; + +--- mysql-test/t/bug40980.test 1970-01-01 01:00:00.000000000 +0100 ++++ mysql-test/t/bug40980.test 2013-06-20 21:41:50.813398500 +0200 +@@ -0,0 +1,29 @@ ++--source include/have_symlink.inc ++--source include/not_windows.inc ++ ++--disable_warnings ++drop table if exists t1,t2,t7,t8,t9; ++drop database if exists mysqltest; ++--enable_warnings ++ ++--echo # ++--echo # BUG#40980 - Drop table can remove another MyISAM table's ++--echo # data and index files ++--echo # ++--mkdir $MYSQL_TMP_DIR/mysql ++--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR ++eval CREATE TABLE user(a INT) DATA DIRECTORY='$MYSQL_TMP_DIR/mysql' ++ INDEX DIRECTORY='$MYSQL_TMP_DIR/mysql'; ++FLUSH TABLE user; ++--echo # Symlinking mysql database to tmpdir ++--remove_file $MYSQL_TMP_DIR/mysql/user.MYD ++--remove_file $MYSQL_TMP_DIR/mysql/user.MYI ++--rmdir $MYSQL_TMP_DIR/mysql ++--exec ln -s $MYSQLD_DATADIR/mysql $MYSQL_TMP_DIR/mysql ++FLUSH TABLE mysql.user; ++DROP TABLE user; ++FLUSH TABLE mysql.user; ++--disable_result_log ++SELECT * FROM mysql.user; ++--enable_result_log ++--remove_file $MYSQL_TMP_DIR/mysql diff -r 54a3a004ee1d -r 70e041ba5b04 components/mysql-5-1/patches/bug68591.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/mysql-5-1/patches/bug68591.patch Wed Jul 17 00:17:02 2013 -0700 @@ -0,0 +1,287 @@ +# Fixes Solaris bug #15688738 +# =========================== + +--- sql/spatial.h revid:joro@sun.com-20090713174543-cd2x7q1gi1hzoand ++++ sql/spatial.h 2013-06-26 05:14:10 +0000 +@@ -324,6 +324,26 @@ + { + return (cur_data + data_amount > m_data_end); + } ++ ++ /** ++ Check if there're enough points remaining as requested ++ ++ Need to perform the calculation in logical units, since multiplication ++ can overflow the size data type. ++ ++ @arg data pointer to the begining of the points array ++ @arg expected_points number of points expected ++ @arg extra_point_space extra space for each point element in the array ++ @return true if there are not enough points ++ */ ++ inline bool not_enough_points(const char *data, uint32 expected_points, ++ uint32 extra_point_space = 0) const ++ { ++ return (m_data_end < data || ++ (expected_points > ((m_data_end - data) / ++ (POINT_DATA_SIZE + extra_point_space)))); ++ } ++ + const char *m_data; + const char *m_data_end; + }; + +=== modified file 'sql/spatial.cc' +--- sql/spatial.cc revid:joro@sun.com-20090713174543-cd2x7q1gi1hzoand ++++ sql/spatial.cc 2013-06-26 05:14:10 +0000 +@@ -393,7 +393,7 @@ + points= uint4korr(data); + data+= 4; + +- if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points)) ++ if (not_enough_points(data, points, offset)) + return 0; + + /* Calculate MBR for points */ +@@ -476,9 +476,16 @@ + + uint32 Gis_line_string::get_data_size() const + { ++ size_t n_points; + if (no_data(m_data, 4)) + return GET_SIZE_ERROR; +- return 4 + uint4korr(m_data) * POINT_DATA_SIZE; ++ ++ n_points= uint4korr(m_data); ++ ++ if (not_enough_points(m_data + 4, n_points)) ++ return GET_SIZE_ERROR; ++ ++ return 4 + n_points * POINT_DATA_SIZE; + } + + +@@ -548,7 +555,7 @@ + data += 4; + + if (n_points < 1 || +- no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) || ++ not_enough_points(data, n_points) || + txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; + +@@ -585,7 +592,7 @@ + return 1; + n_points= uint4korr(data); + data+= 4; +- if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) ++ if (n_points < 1 || not_enough_points(data, n_points)) + return 1; + + get_point(&prev_x, &prev_y, data); +@@ -619,7 +626,7 @@ + return 0; + } + data+= 4; +- if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) ++ if (n_points == 0 || not_enough_points(data, n_points)) + return 1; + + /* Get first point */ +@@ -690,9 +697,16 @@ + + while (n_linear_rings--) + { ++ size_t n_points; + if (no_data(data, 4)) + return GET_SIZE_ERROR; +- data+= 4 + uint4korr(data)*POINT_DATA_SIZE; ++ n_points= uint4korr(data); ++ data+= 4; ++ ++ if (not_enough_points(data, n_points)) ++ return GET_SIZE_ERROR; ++ ++ data+= n_points * POINT_DATA_SIZE; + } + return (uint32) (data - m_data); + } +@@ -786,8 +800,9 @@ + return 1; + n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) || +- txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) ++ ++ if (not_enough_points(data, n_points) || ++ txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) + return 1; + txt->qs_append('('); + data= append_points(txt, n_points, data, 0); +@@ -840,7 +855,7 @@ + if (no_data(data, 4)) + return 1; + n_points= uint4korr(data); +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) ++ if (not_enough_points(data, n_points)) + return 1; + get_point(&prev_x, &prev_y, data+4); + data+= (4+SIZEOF_STORED_DOUBLE*2); +@@ -876,7 +891,7 @@ + n_points= uint4korr(data); + data+= 4; + length= n_points * POINT_DATA_SIZE; +- if (no_data(data, length) || result->reserve(1+4+4+ length)) ++ if (not_enough_points(data, n_points) || result->reserve(1+4+4+ length)) + return 1; + + result->q_append((char) wkb_ndr); +@@ -922,7 +937,7 @@ + n_points= uint4korr(data); + points_size= n_points * POINT_DATA_SIZE; + data+= 4; +- if (no_data(data, points_size) || result->reserve(1+4+4+ points_size)) ++ if (not_enough_points(data, n_points) || result->reserve(1+4+4+ points_size)) + return 1; + + result->q_append((char) wkb_ndr); +@@ -964,7 +979,7 @@ + return 1; + org_n_points= n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) ++ if (not_enough_points(data, n_points)) + return 1; + get_point(&prev_x, &prev_y, data); + data+= (SIZEOF_STORED_DOUBLE*2); +@@ -1021,14 +1036,21 @@ + + /***************************** MultiPoint *******************************/ + +-uint32 Gis_multi_point::get_data_size() const ++uint32 Gis_multi_point::get_data_size() const + { ++ size_t n_points; ++ + if (no_data(m_data, 4)) + return GET_SIZE_ERROR; +- return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE); ++ ++ n_points= uint4korr(m_data); ++ ++ if (not_enough_points(m_data + 4, n_points, WKB_HEADER_SIZE)) ++ return GET_SIZE_ERROR; ++ ++ return 4 + n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE); + } + +- + bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb) + { + uint32 n_points= 0; +@@ -1085,24 +1107,26 @@ + return proper_size; + } + +- + bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const + { + uint32 n_points; +- if (no_data(m_data, 4)) ++ const char *data= m_data; ++ ++ if (no_data(data, 4)) + return 1; + +- n_points= uint4korr(m_data); +- if (no_data(m_data+4, +- n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) || ++ n_points= uint4korr(data); ++ data+= 4; ++ ++ if (not_enough_points(data, n_points, WKB_HEADER_SIZE) || + txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) + return 1; +- *end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE); +- txt->length(txt->length()-1); // Remove end ',' ++ ++ *end= append_points(txt, n_points, data, WKB_HEADER_SIZE); ++ txt->length(txt->length()-1); // Remove end ',' + return 0; + } + +- + bool Gis_multi_point::get_mbr(MBR *mbr, const char **end) const + { + return (*end= get_mbr_for_points(mbr, m_data, WKB_HEADER_SIZE)) == 0; +@@ -1155,11 +1179,20 @@ + + while (n_line_strings--) + { ++ size_t n_points; ++ + if (no_data(data, WKB_HEADER_SIZE + 4)) + return GET_SIZE_ERROR; +- data+= (WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) * +- POINT_DATA_SIZE); ++ ++ n_points= uint4korr(data + WKB_HEADER_SIZE); ++ data+= WKB_HEADER_SIZE + 4; ++ ++ if (not_enough_points(data, n_points)) ++ return GET_SIZE_ERROR; ++ ++ data+= n_points * POINT_DATA_SIZE; + } ++ + return (uint32) (data - m_data); + } + +@@ -1251,7 +1284,7 @@ + return 1; + n_points= uint4korr(data + WKB_HEADER_SIZE); + data+= WKB_HEADER_SIZE + 4; +- if (no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || ++ if (not_enough_points(data, n_points) || + txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) + return 1; + txt->qs_append('('); +@@ -1312,7 +1345,7 @@ + return 1; + n_points= uint4korr(data + WKB_HEADER_SIZE); + length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points; +- if (no_data(data, length)) ++ if (not_enough_points(data + WKB_HEADER_SIZE + 4, n_points)) + return 1; + if (!--num) + break; +@@ -1410,9 +1443,16 @@ + + while (n_linear_rings--) + { ++ size_t n_points; + if (no_data(data, 4)) +- return GET_SIZE_ERROR; +- data+= 4 + uint4korr(data) * POINT_DATA_SIZE; ++ return GET_SIZE_ERROR; ++ n_points= uint4korr(data); ++ data+= 4; ++ ++ if (not_enough_points(data, n_points)) ++ return GET_SIZE_ERROR; ++ ++ data+= n_points * POINT_DATA_SIZE; + } + } + return (uint32) (data - m_data); +@@ -1512,7 +1552,7 @@ + return 1; + uint32 n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || ++ if (not_enough_points(data, n_points) || + txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points, + 512)) + return 1; + +=== modified file 'sql/spatial.h'