Commit 9e6a5959 authored by unknown's avatar unknown
Browse files

Bug #26303: Reserve is not called before qs_append().

This may lead to buffer overflow.
The String::qs_append() function will append a string
without checking if there's enough space.
So qs_append() must be called beforehand to ensure 
there's enough space in the buffer for the subsequent 
qs_append() calls.
Fixed Item_case_expr::print() to make sure there's
enough space before appending data by adding a call to 
String::reserve() to make sure qs_append() will have 
enough space.


mysql-test/r/sp-code.result:
  Bug #26303: test case
mysql-test/t/sp-code.test:
  Bug #26303: test case
sql/item.cc:
  Bug #26303: added a call to String::reserve() to
   make sure qs_append will have enough space
sql/item.h:
  Bug #26303: m_case_expr_id made unsigned 
  because it's offset in an array.
parent c2426620
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -621,3 +621,20 @@ Pos Instruction
0	stmt 2 "CREATE INDEX idx ON t1 (c1)"
DROP PROCEDURE p1;
End of 5.0 tests.
CREATE PROCEDURE p1() 
BEGIN 
DECLARE dummy int default 0;
CASE 12 
WHEN 12 
THEN SET dummy = 0;
END CASE;
END//
SHOW PROCEDURE CODE p1;
Pos	Instruction
0	set dummy@0 0
1	set_case_expr (6) 0 12
2	jump_if_not 5(6) (case_expr@0 = 12)
3	set dummy@0 0
4	jump 6
5	error 1339
DROP PROCEDURE p1;
+18 −0
Original line number Diff line number Diff line
@@ -447,3 +447,21 @@ DROP PROCEDURE p1;


--echo End of 5.0 tests.

#
# Bug #26303: reserve() not called before qs_append() may lead to buffer
# overflow
#
DELIMITER //;
CREATE PROCEDURE p1() 
BEGIN 
  DECLARE dummy int default 0;

  CASE 12 
    WHEN 12 
    THEN SET dummy = 0;
  END CASE;
END//
DELIMITER ;//
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
+3 −1
Original line number Diff line number Diff line
@@ -1088,7 +1088,7 @@ bool Item_splocal::set_value(THD *thd, sp_rcontext *ctx, Item **it)
  Item_case_expr methods
*****************************************************************************/

Item_case_expr::Item_case_expr(int case_expr_id)
Item_case_expr::Item_case_expr(uint case_expr_id)
  :Item_sp_variable( C_STRING_WITH_LEN("case_expr")),
   m_case_expr_id(case_expr_id)
{
@@ -1125,6 +1125,8 @@ Item_case_expr::this_item_addr(THD *thd, Item **)

void Item_case_expr::print(String *str)
{
  if (str->reserve(MAX_INT_WIDTH + sizeof("case_expr@")))
    return;                                    /* purecov: inspected */
  VOID(str->append(STRING_WITH_LEN("case_expr@")));
  str->qs_append(m_case_expr_id);
}
+2 −2
Original line number Diff line number Diff line
@@ -1116,7 +1116,7 @@ inline Item_result Item_splocal::result_type() const
class Item_case_expr :public Item_sp_variable
{
public:
  Item_case_expr(int case_expr_id);
  Item_case_expr(uint case_expr_id);

public:
  Item *this_item();
@@ -1135,7 +1135,7 @@ class Item_case_expr :public Item_sp_variable
  void print(String *str);

private:
  int m_case_expr_id;
  uint m_case_expr_id;
};

/*****************************************************************************