Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0fAA-0026MS-3B for pgsql-bugs@arkaria.postgresql.org; Thu, 12 Mar 2026 12:29:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w0fA9-00EmHY-1F for pgsql-bugs@arkaria.postgresql.org; Thu, 12 Mar 2026 12:29:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0Zaa-00DVJz-2l for pgsql-bugs@lists.postgresql.org; Thu, 12 Mar 2026 06:32:09 +0000 Received: from mahout.postgresql.org ([2001:4800:3e1:1::227]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1w0ZaY-00000002G5N-0j1O for pgsql-bugs@lists.postgresql.org; Thu, 12 Mar 2026 06:32:08 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Message-ID:Date:Reply-To:Cc:From:To:Subject: Content-Transfer-Encoding:MIME-Version:Content-Type:Sender:Content-ID: Content-Description:In-Reply-To:References; bh=C0y6hzz1ZGVFzxNfz7OzQ7PgZA7Bp2LkQBbW21+5QHI=; b=4ny9G8tp78Y+bjqOBVYWMo4qaB Fy2H2MQxXuBdLQsd97iE59BVaJJ2b1AxPzPNlJ754euWLd8Bp7FHOTcY1mmzWFeacZR37Bc4aShYd z0pEKQO6pF9N99in2C6zOPuiNsYpkxm6GLWPlJebszVpN0+ntrPWocaU33ealFYbyI/QlG6dzl4pn ZS1/q5Jezxfn9DzP9zvPswyQO10aKYWSiGi4WRHEZK7GW1foovnTO6J1ONmAu2M7U+FqtGQQeDCBF EYfo5hz29SHMXNcjtxQypSNAOGG5d/JVXGOtGR1ZkkVcD+o5smTxape5a0nhLt1yZ9rjLu2JmTv4S k7rkaWFA==; Received: from wrigleys.postgresql.org ([2a02:16a8:dc51::60]) by mahout.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0ZaX-004GtT-0B for pgsql-bugs@lists.postgresql.org; Thu, 12 Mar 2026 06:32:05 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w0ZaT-008i5X-2H for pgsql-bugs@lists.postgresql.org; Thu, 12 Mar 2026 06:32:02 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19429: An issue regarding the processing of Oid as an int type in ecpg To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: fairyfar@msn.com Reply-To: fairyfar@msn.com, pgsql-bugs@lists.postgresql.org Date: Thu, 12 Mar 2026 06:31:58 +0000 Message-ID: <19429-aead3b1874be1a99@postgresql.org> X-Auto-Response-Suppress: All Auto-Submitted: auto-generated List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk The following bug has been logged on the website: Bug reference: 19429 Logged by: fairyfar Email address: fairyfar@msn.com PostgreSQL version: 18.3 Operating system: Linux Description: =20 An issue regarding the processing of Oid as an int type in ecpg. PostgreSQL version: 18.3 (the other ones are the same). Part of the code caches and calculates the Oid as an int type in ecpg. We know that Oid is unsigned int. When the Oid value is greater than or equal to 2^31, it exceeds the value range of the int type. There are potential problems in processing Oid with the int type. For example, when formatting Oid with "%d", negative values may occur. Through analysis and testing, it is found that the ecpg part of the code has not caused any problems so far, but it is running in an obscure way. For example, suppose the current value of Oid next is 2^31, the user creates a custom data type and creates a table using this type: ```sql -- An array type named _mytype will be automatically created. -- Suppose the Oid of the _mytype type created by the following SQL is 2147483648 (i.e., 2^31). create type mytype as (x int, y int); create table t1 (a _mytype); insert into t1 values (array[row(111, 222)::mytype]); ``` Use the following test.pgc code to read the data in table t1: ``` int main() { EXEC SQL BEGIN DECLARE SECTION; char str[256]; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT TO 'tcp:postgresql://localhost:5432/postgres' as ffdb USER fairyfar; EXEC SQL SELECT a INTO :str FROM t1; printf("%s\n", str); EXEC SQL DISCONNECT ffdb; return 0; } ``` After compiling, running and debugging the code. It can be known that the content of array_query variable will be set as "select typlen from pg_type where oid=3D-2147483648 and typelem<>0" on src/interfaces/ecpg/ecpglib/execute.c:270. Although this select query can be executed correctly, it is running in a strange and coincidental way: 1. The Oid passes a negative value. 2. In grammar parsing, the pg_strtoint32_safe function enters the "out of range" logic, but does not explicitly report an error. It is recommended to make the following patches to eliminate potential risks. ``` diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index 949ff66cefc..bea1398fce8 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -52,7 +52,7 @@ struct ECPGgeneric_bytea struct ECPGtype_information_cache { struct ECPGtype_information_cache *next; - int oid; + Oid oid; enum ARRAY_TYPE isarray; }; =20 diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index bd10fef5748..b8dd0861ef6 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -145,7 +145,7 @@ next_insert(char *text, int pos, bool questionmarks, bool std_strings) } =20 static bool -ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, int oid, enum ARRAY_TYPE isarray, int lineno) +ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, Oid oid, enum ARRAY_TYPE isarray, int lineno) { struct ECPGtype_information_cache *new_entry =3D (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno); @@ -161,7 +161,7 @@ ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, int oid, enu } =20 static enum ARRAY_TYPE -ecpg_is_type_an_array(int type, const struct statement *stmt, const struct variable *var) +ecpg_is_type_an_array(Oid type, const struct statement *stmt, const struct variable *var) { char *array_query; enum ARRAY_TYPE isarray =3D ECPG_ARRAY_NOT_SET; @@ -267,7 +267,7 @@ ecpg_is_type_an_array(int type, const struct statement *stmt, const struct varia if (array_query =3D=3D NULL) return ECPG_ARRAY_ERROR; =20 - sprintf(array_query, "select typlen from pg_type where oid=3D%d and typelem<>0", type); + sprintf(array_query, "select typlen from pg_type where oid=3D%u and typelem<>0", type); query =3D PQexec(stmt->connection->connection, array_query); ecpg_free(array_query); if (!ecpg_check_PQresult(query, stmt->lineno, stmt->connection->connection, stmt->compat)) @@ -294,7 +294,7 @@ ecpg_is_type_an_array(int type, const struct statement *stmt, const struct varia return ECPG_ARRAY_ERROR; =20 ecpg_type_infocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno); - ecpg_log("ecpg_is_type_an_array on line %d: type (%d); C (%d); array (%s)\n", stmt->lineno, type, var->type, ECPG_IS_ARRAY(isarray) ? "yes" : "no"); + ecpg_log("ecpg_is_type_an_array on line %d: type (%u); C (%d); array (%s)\n", stmt->lineno, type, var->type, ECPG_IS_ARRAY(isarray) ? "yes" : "no"); return isarray; } ```