From: Tor Didriksen Date: May 12 2011 2:35pm Subject: bzr commit into mysql-trunk branch (tor.didriksen:3372) Bug#11765562 List-Archive: http://lists.mysql.com/commits/137241 X-Bug: 11765562 Message-Id: <20110512143532.F41C03793@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0290617775947986242==" --===============0290617775947986242== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/didrik/repo/trunk-bug11765562/ based on revid:tatjana.nuernberg@stripped 3372 Tor Didriksen 2011-05-03 Bug#11765562 58545 EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE The function EXPORT_SET(bits,on,off[,separator[,number_of_bits]]) will concatenate (up to) 64*2 -1 strings: on/off and separator. The total length should not be greater than thd->variables.max_allowed_packet. @ sql/item_strfunc.cc In Item_func_export_set::val_str, verify that the size of the end result is within reasonable bounds. @ unittest/gunit/item-t.cc New test cases. Fix an EXPECT_EQ call: the expected value should be first. modified: sql/item_strfunc.cc unittest/gunit/item-t.cc === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2011-05-06 13:32:53 +0000 +++ b/sql/item_strfunc.cc 2011-05-03 08:51:46 +0000 @@ -3437,23 +3437,21 @@ err: String* Item_func_export_set::val_str(String* str) { DBUG_ASSERT(fixed == 1); - ulonglong the_set = (ulonglong) args[0]->val_int(); - String yes_buf, *yes; - yes = args[1]->val_str(&yes_buf); - String no_buf, *no; - no = args[2]->val_str(&no_buf); - String *sep = NULL, sep_buf ; + String yes_buf, no_buf, sep_buf; + const ulonglong the_set = (ulonglong) args[0]->val_int(); + const String *yes= args[1]->val_str(&yes_buf); + const String *no= args[2]->val_str(&no_buf); + const String *sep= NULL; uint num_set_values = 64; - ulonglong mask = 0x1; str->length(0); str->set_charset(collation.collation); /* Check if some argument is a NULL value */ if (args[0]->null_value || args[1]->null_value || args[2]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Arg count can only be 3, 4 or 5 here. This is guaranteed from the @@ -3466,37 +3464,62 @@ String* Item_func_export_set::val_str(St num_set_values=64; if (args[4]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Fall through */ case 4: if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL { - null_value=1; - return 0; + null_value= true; + return NULL; } break; case 3: { /* errors is not checked - assume "," can always be converted */ uint errors; - sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors); + sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, + collation.collation, &errors); sep = &sep_buf; } break; default: DBUG_ASSERT(0); // cannot happen } - null_value=0; + null_value= false; + + ulonglong total_length= 0; + ulonglong mask; + uint ix; + for (ix= 0, mask= 0x1; ix < num_set_values; ++ix, mask= (mask << 1)) + { + if (the_set & mask) + total_length+= yes->length(); + else + total_length+= no->length(); + if (ix != num_set_values - 1) + total_length+= sep->length(); + } + + if (total_length > current_thd->variables.max_allowed_packet) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_ALLOWED_PACKET_OVERFLOWED, + ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), + func_name(), current_thd->variables.max_allowed_packet); + null_value= true; + return NULL; + } - for (uint i = 0; i < num_set_values; i++, mask = (mask << 1)) + str->reserve(static_cast(total_length)); + for (ix= 0, mask=0x1; ix < num_set_values; ++ix, mask = (mask << 1)) { if (the_set & mask) str->append(*yes); else str->append(*no); - if (i != num_set_values - 1) + if (ix != num_set_values - 1) str->append(*sep); } return str; === modified file 'unittest/gunit/item-t.cc' --- a/unittest/gunit/item-t.cc 2011-03-18 12:25:56 +0000 +++ b/unittest/gunit/item-t.cc 2011-05-03 08:51:46 +0000 @@ -66,10 +66,12 @@ public: const char* msg, MYSQL_ERROR ** cond_hdl) { - EXPECT_EQ(sql_errno, m_expected_error); + EXPECT_EQ(m_expected_error, sql_errno); ++m_handle_called; return true; } + + int handle_called() const { return m_handle_called; } private: THD *m_thd; uint m_expected_error; @@ -246,6 +248,88 @@ TEST_F(ItemTest, ItemFuncDesDecrypt) } +TEST_F(ItemTest, ItemFuncExportSet) +{ + String str; + Item *on_string= new Item_string(STRING_WITH_LEN("on"), &my_charset_bin); + Item *off_string= new Item_string(STRING_WITH_LEN("off"), &my_charset_bin); + Item *sep_string= new Item_string(STRING_WITH_LEN(","), &my_charset_bin); + { + // Testing basic functionality. + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(2), + on_string, + off_string, + sep_string, + new Item_int(4)); + EXPECT_FALSE(export_set->fix_fields(m_thd, NULL)); + EXPECT_EQ(&str, export_set->val_str(&str)); + EXPECT_STREQ("off,on,off,off", str.c_ptr_safe()); + } + { + // Testing corner case: number_of_bits == zero. + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(2), + on_string, + off_string, + sep_string, + new Item_int(0)); + EXPECT_FALSE(export_set->fix_fields(m_thd, NULL)); + EXPECT_EQ(&str, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + } + + /* + Bug#11765562 58545: + EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE + */ + const ulong max_size= 1024; + const ulonglong repeat= max_size / 2; + Item *item_int_repeat= new Item_int(repeat); + Item *string_x= new Item_string(STRING_WITH_LEN("x"), &my_charset_bin); + m_thd->variables.max_allowed_packet= max_size; + { + // Testing overflow caused by 'on-string'. + Mock_error_handler error_handler(m_thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + new Item_func_repeat(string_x, item_int_repeat), + string_x, + sep_string); + EXPECT_FALSE(export_set->fix_fields(m_thd, NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } + { + // Testing overflow caused by 'off-string'. + Mock_error_handler error_handler(m_thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + string_x, + new Item_func_repeat(string_x, item_int_repeat), + sep_string); + EXPECT_FALSE(export_set->fix_fields(m_thd, NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } + { + // Testing overflow caused by 'separator-string'. + Mock_error_handler error_handler(m_thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + string_x, + string_x, + new Item_func_repeat(string_x, item_int_repeat)); + EXPECT_FALSE(export_set->fix_fields(m_thd, NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } +} + + TEST_F(ItemTest, ItemFuncIntDivOverflow) { const char dividend_str[]= --===============0290617775947986242== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/tor.didriksen@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: tor.didriksen@stripped\ # vdcqepjt0t31bvok # target_branch: file:///export/home/didrik/repo/trunk-bug11765562/ # testament_sha1: 6a934c7ace36253125eea96519210d10acac31ff # timestamp: 2011-05-12 16:35:32 +0200 # base_revision_id: tatjana.nuernberg@stripped\ # d356g1nkucpvaa6e # # Begin bundle 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 --===============0290617775947986242==--