Thread

Commits

  1. Be more careful about int vs. Oid in ecpglib.

  1. BUG #19429: An issue regarding the processing of Oid as an int type in ecpg

    The Post Office <noreply@postgresql.org> — 2026-03-12T06:31:58Z

    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:        
    
    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=-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;
     };
     
    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)
     }
     
     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
            = (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
     }
     
     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 = 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 == NULL)
                    return ECPG_ARRAY_ERROR;
     
    -       sprintf(array_query, "select typlen from pg_type where oid=%d and
    typelem<>0", type);
    +       sprintf(array_query, "select typlen from pg_type where oid=%u and
    typelem<>0", type);
            query = 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;
     
            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;
     }
    ```
    
    
    
    
    
    
  2. Re: BUG #19429: An issue regarding the processing of Oid as an int type in ecpg

    Tom Lane <tgl@sss.pgh.pa.us> — 2026-03-15T23:00:28Z

    PG Bug reporting form <noreply@postgresql.org> writes:
    > 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.
    
    Yeah, it does work as-is, but it's relying on undocumented details
    about what the server will do with something like "oid=-1".
    
    I reviewed your patch and pushed it.  For future reference, it's not
    great to send patches via our bug report form; whitespace gets mangled
    and it's quite painful to reconstruct.  Better to just send email to
    pgsql-hackers with the patch in an attachment.
    
    			regards, tom lane