From 3fff98d49390a07518ccd771b9f64e29e779e7f2 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Wed, 3 Jun 2026 14:14:11 +0200 Subject: [PATCH] Avoid integer overflow in query parameter encoding Many large bytea parameters wrapped the typecast buffer size, then the bytea encoder wrote past the allocation. Fixes #719 --- ext/pg_connection.c | 2 +- spec/pg/connection_spec.rb | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ext/pg_connection.c b/ext/pg_connection.c index c8b71d67b..c7478ad3c 100644 --- a/ext/pg_connection.c +++ b/ext/pg_connection.c @@ -1281,7 +1281,7 @@ alloc_query_params(struct query_params_data *paramsData) int nParams; int i=0; t_pg_coder *conv; - unsigned int required_pool_size; + size_t required_pool_size; char *memory_pool; Check_Type(paramsData->params, T_ARRAY); diff --git a/spec/pg/connection_spec.rb b/spec/pg/connection_spec.rb index fdae1b2b7..716493788 100644 --- a/spec/pg/connection_spec.rb +++ b/spec/pg/connection_spec.rb @@ -2855,6 +2855,25 @@ def wait_check_socket(conn) end end + it "should encode big strings with typecasting without overflow" do + big_count = 100 + step = 42_949_673 + big_len = (step - 3) / 2 + wrap = (big_count * step) & 0xffff_ffff + + big = 'A'.b * big_len + params = Array.new(big_count, big) + + tm = PG::TypeMapByClass.new + tm[String] = PG::TextEncoder::Bytea.new.freeze + + sql = big_count.times.map{|n| "$#{n+1}" }.join(",") + @conn.exec_params('select '+sql, params, 0, tm) + rescue PG::UnableToSend + # ignore "PQsendQueryParams cannot allocate memory for output buffer" + end + + it "can process #copy_data input queries with row encoder and respects character encoding" do @conn2.exec( "CREATE TEMP TABLE copytable (col1 TEXT)" ) @conn2.copy_data( "COPY copytable FROM STDOUT" ) do |res|