From 38b431801a9f5fa7fabc3740522180b6e48621a1 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Thu, 27 Apr 2023 20:06:23 +0200 Subject: [PATCH] Fix possible segfault when creating new PG::Result Initialize connection and typemap prior to any object allocations, to make sure valid objects are marked. This regression was introduced in commit 5061020c28d694464a5fa5474062d8486912daa1 while introducing write barriers. However it is not necessary to use RB_OBJ_WRITE when the "old" object (1st argument) is not yet created or immediately after it was created. The initial assignment can and must be done before processing the typemap as it was before the above commit. Fixes #530 --- ext/pg_result.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ext/pg_result.c b/ext/pg_result.c index 67b456d3a..c8794b5c9 100644 --- a/ext/pg_result.c +++ b/ext/pg_result.c @@ -208,12 +208,16 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn) this = (t_pg_result *)xmalloc(sizeof(*this) + sizeof(*this->fnames) * nfields); this->pgresult = result; + /* Initialize connection and typemap prior to any object allocations, + * to make sure valid objects are marked. */ + this->connection = rb_pgconn; + this->typemap = pg_typemap_all_strings; + this->p_typemap = RTYPEDDATA_DATA( this->typemap ); this->nfields = -1; this->tuple_hash = Qnil; this->field_map = Qnil; this->flags = 0; self = TypedData_Wrap_Struct(rb_cPGresult, &pgresult_type, this); - RB_OBJ_WRITE(self, &this->connection, rb_pgconn); if( result ){ t_pg_connection *p_conn = pg_get_connection(rb_pgconn); @@ -227,8 +231,6 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn) this->p_typemap = RTYPEDDATA_DATA( this->typemap ); this->flags = p_conn->flags; } else { - RB_OBJ_WRITE(self, &this->typemap, pg_typemap_all_strings); - this->p_typemap = RTYPEDDATA_DATA( this->typemap ); this->enc_idx = rb_locale_encindex(); }