diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index c6a9dab..f6c947a 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -342,15 +342,15 @@ static VALUE rb_mysql_client_escape(VALUE self, VALUE str) { #endif oldLen = RSTRING_LEN(str); - char escaped[(oldLen*2)+1]; + newStr = rb_str_new(0, oldLen*2+1); REQUIRE_OPEN_DB(client); - newLen = mysql_real_escape_string(client, escaped, StringValuePtr(str), oldLen); + newLen = mysql_real_escape_string(client, RSTRING_PTR(newStr), StringValuePtr(str), oldLen); if (newLen == oldLen) { // no need to return a new ruby string if nothing changed return str; } else { - newStr = rb_str_new(escaped, newLen); + rb_str_resize(newStr, newLen); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(newStr, conn_enc); if (default_internal_enc) { diff --git a/spec/mysql2/client_spec.rb b/spec/mysql2/client_spec.rb index b3ffcbc..936e1ea 100644 --- a/spec/mysql2/client_spec.rb +++ b/spec/mysql2/client_spec.rb @@ -144,6 +144,18 @@ describe Mysql2::Client do @client.escape(str).object_id.should eql(str.object_id) end + it "#escape should not overflow the thread stack" do + lambda { + Thread.new { @client.escape("'" * 256 * 1024) }.join + }.should_not raise_error(SystemStackError) + end + + it "#escape should not overflow the process stack" do + lambda { + Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join + }.should_not raise_error(SystemStackError) + end + it "should respond to #info" do @client.should respond_to(:info) end