Adapt appendPsqlMetaConnect() to the new fmtId() encoding expectations.
authorTom Lane <[email protected]>
Mon, 10 Feb 2025 21:30:03 +0000 (16:30 -0500)
committerTom Lane <[email protected]>
Mon, 10 Feb 2025 21:31:01 +0000 (16:31 -0500)
We need to tell fmtId() what encoding to assume, but this function
doesn't know that.  Fortunately we can fix that without changing the
function's API, because we can just use SQL_ASCII.  That's because
database names in connection requests are effectively binary not text:
no encoding-aware processing will happen on them.

This fixes XversionUpgrade failures seen in the buildfarm.  The
alternative of having pg_upgrade use setFmtEncoding() is unappetizing,
given that it's connecting to multiple databases that may have
different encodings.

Andres Freund, Noah Misch, Tom Lane

Security: CVE-2025-1094

src/fe_utils/string_utils.c

index 9131b471cd51920579bf4128f439daacd25ea7ac..ba409e638794a4e2b05451aa405caecbbaa7a46d 100644 (file)
@@ -790,29 +790,38 @@ appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
        }
    }
 
-   appendPQExpBufferStr(buf, "\\connect ");
    if (complex)
    {
        PQExpBufferData connstr;
 
        initPQExpBuffer(&connstr);
+
+       /*
+        * Force the target psql's encoding to SQL_ASCII.  We don't really
+        * know the encoding of the database name, and it doesn't matter as
+        * long as psql will forward it to the server unchanged.
+        */
+       appendPQExpBufferStr(buf, "\\encoding SQL_ASCII\n");
+       appendPQExpBufferStr(buf, "\\connect -reuse-previous=on ");
+
        appendPQExpBufferStr(&connstr, "dbname=");
        appendConnStrVal(&connstr, dbname);
 
-       appendPQExpBufferStr(buf, "-reuse-previous=on ");
-
        /*
         * As long as the name does not contain a newline, SQL identifier
         * quoting satisfies the psql meta-command parser.  Prefer not to
         * involve psql-interpreted single quotes, which behaved differently
         * before PostgreSQL 9.2.
         */
-       appendPQExpBufferStr(buf, fmtId(connstr.data));
+       appendPQExpBufferStr(buf, fmtIdEnc(connstr.data, PG_SQL_ASCII));
 
        termPQExpBuffer(&connstr);
    }
    else
-       appendPQExpBufferStr(buf, fmtId(dbname));
+   {
+       appendPQExpBufferStr(buf, "\\connect ");
+       appendPQExpBufferStr(buf, fmtIdEnc(dbname, PG_SQL_ASCII));
+   }
    appendPQExpBufferChar(buf, '\n');
 }