diff --git a/ext/pg_text_encoder.c b/ext/pg_text_encoder.c index e465a15d2..826e85728 100644 --- a/ext/pg_text_encoder.c +++ b/ext/pg_text_encoder.c @@ -430,9 +430,14 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, } return (int)(optr - out); }else{ + long size; *intermediate = rb_obj_as_string(value); + size = RSTRING_LEN(*intermediate); + /* The output starts with "\x" and each character is converted to hex. */ - return 2 + RSTRING_LENINT(*intermediate) * 2; + if( size > INT_MAX / 2 - 2 ) + rb_raise( rb_eArgError, "too large input string for PG::TextEncoder::Bytea: %ld", size ); + return 2 + size * 2; } } diff --git a/spec/pg/type_spec.rb b/spec/pg/type_spec.rb index ad5e5f9b0..c69e35215 100644 --- a/spec/pg/type_spec.rb +++ b/spec/pg/type_spec.rb @@ -392,6 +392,15 @@ def textdec_timestamptz_decode_should_fail(str) expect( textenc_bytea.encode("\x00\x01\x02\x03\xef".b) ).to eq( "\\x00010203ef" ) end + it "should raise too large string to bytea" do + n = 1_073_741_822 + data = "A".b * n + enc = PG::TextEncoder::ToBase64.new( + elements_type: PG::TextEncoder::Bytea.new + ) + expect{ enc.encode(data) }.to raise_error(ArgumentError, /too large input string/) + end + context 'text timestamps' do it 'encodes timestamps without timezone' do expect( textenc_timestamp.encode(Time.new(2016,1,2, 23, 23, 59.123456, 3*60*60)) ).