diff options
| author | Andres Freund | 2025-02-10 15:03:40 +0000 |
|---|---|---|
| committer | Andres Freund | 2025-02-10 15:03:40 +0000 |
| commit | 5df4e1632e65323ad9b33d7dfe721117a6060fbe (patch) | |
| tree | 69dd095229a523158fc7341412beea65f16229c1 /src/bin | |
| parent | db3eb0e8256a7089d16cb6ed1ea7a65654c0e105 (diff) | |
Specify the encoding of input to fmtId()
This commit adds fmtIdEnc() and fmtQualifiedIdEnc(), which allow to specify
the encoding as an explicit argument. Additionally setFmtEncoding() is
provided, which defines the encoding when no explicit encoding is provided, to
avoid breaking all code using fmtId().
All users of fmtId()/fmtQualifiedId() are either converted to the explicit
version or a call to setFmtEncoding() has been added.
This commit does not yet utilize the now well-defined encoding, that will
happen in a subsequent commit.
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 13
Security: CVE-2025-1094
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/pg_dump/pg_backup_archiver.c | 1 | ||||
| -rw-r--r-- | src/bin/pg_dump/pg_dump.c | 1 | ||||
| -rw-r--r-- | src/bin/pg_dump/pg_dumpall.c | 1 | ||||
| -rw-r--r-- | src/bin/psql/command.c | 3 | ||||
| -rw-r--r-- | src/bin/scripts/common.c | 5 | ||||
| -rw-r--r-- | src/bin/scripts/createdb.c | 2 | ||||
| -rw-r--r-- | src/bin/scripts/createuser.c | 2 | ||||
| -rw-r--r-- | src/bin/scripts/dropdb.c | 13 | ||||
| -rw-r--r-- | src/bin/scripts/dropuser.c | 3 | ||||
| -rw-r--r-- | src/bin/scripts/reindexdb.c | 8 | ||||
| -rw-r--r-- | src/bin/scripts/vacuumdb.c | 5 |
11 files changed, 29 insertions, 15 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 4c4b301a347..1040b1b6b65 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -2725,6 +2725,7 @@ processEncodingEntry(ArchiveHandle *AH, TocEntry *te) fatal("unrecognized encoding \"%s\"", ptr1); AH->public.encoding = encoding; + setFmtEncoding(encoding); } else fatal("invalid ENCODING item: %s", diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c83e89b87d5..4c098f20ad3 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -1094,6 +1094,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * we know how to escape strings. */ AH->encoding = PQclientEncoding(conn); + setFmtEncoding(AH->encoding); std_strings = PQparameterStatus(conn, "standard_conforming_strings"); AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 1cf8d20829e..1b4c8c0b090 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -507,6 +507,7 @@ main(int argc, char *argv[]) * we know how to escape strings. */ encoding = PQclientEncoding(conn); + setFmtEncoding(encoding); std_strings = PQparameterStatus(conn, "standard_conforming_strings"); if (!std_strings) std_strings = "off"; diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 506187cfdd5..a00d1b86785 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1220,6 +1220,7 @@ exec_command_encoding(PsqlScanState scan_state, bool active_branch) /* save encoding info into psql internal data */ pset.encoding = PQclientEncoding(pset.db); pset.popt.topt.encoding = pset.encoding; + setFmtEncoding(pset.encoding); SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); } @@ -3606,6 +3607,8 @@ SyncVariables(void) pset.popt.topt.encoding = pset.encoding; pset.sversion = PQserverVersion(pset.db); + setFmtEncoding(pset.encoding); + SetVariable(pset.vars, "DBNAME", PQdb(pset.db)); SetVariable(pset.vars, "USER", PQuser(pset.db)); SetVariable(pset.vars, "HOST", PQhost(pset.db)); diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index d446d7af9fa..8b56ba156ab 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -430,8 +430,9 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec, exit(1); } appendPQExpBufferStr(buf, - fmtQualifiedId(PQgetvalue(res, 0, 1), - PQgetvalue(res, 0, 0))); + fmtQualifiedIdEnc(PQgetvalue(res, 0, 1), + PQgetvalue(res, 0, 0), + PQclientEncoding(conn))); appendPQExpBufferStr(buf, columns); PQclear(res); termPQExpBuffer(&sql); diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c index 91e6e2194bd..5e5190d613e 100644 --- a/src/bin/scripts/createdb.c +++ b/src/bin/scripts/createdb.c @@ -190,6 +190,8 @@ main(int argc, char *argv[]) conn = connectMaintenanceDatabase(&cparams, progname, echo); + setFmtEncoding(PQclientEncoding(conn)); + initPQExpBuffer(&sql); appendPQExpBuffer(&sql, "CREATE DATABASE %s", diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index a15d21f2643..6ee5b324a6e 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -266,6 +266,8 @@ main(int argc, char *argv[]) conn = connectMaintenanceDatabase(&cparams, progname, echo); + setFmtEncoding(PQclientEncoding(conn)); + initPQExpBuffer(&sql); printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser)); diff --git a/src/bin/scripts/dropdb.c b/src/bin/scripts/dropdb.c index ccbf78e91a8..02ebaedd494 100644 --- a/src/bin/scripts/dropdb.c +++ b/src/bin/scripts/dropdb.c @@ -127,13 +127,6 @@ main(int argc, char *argv[]) exit(0); } - initPQExpBuffer(&sql); - - appendPQExpBuffer(&sql, "DROP DATABASE %s%s%s;", - (if_exists ? "IF EXISTS " : ""), - fmtId(dbname), - force ? " WITH (FORCE)" : ""); - /* Avoid trying to drop postgres db while we are connected to it. */ if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) maintenance_db = "template1"; @@ -147,6 +140,12 @@ main(int argc, char *argv[]) conn = connectMaintenanceDatabase(&cparams, progname, echo); + initPQExpBuffer(&sql); + appendPQExpBuffer(&sql, "DROP DATABASE %s%s%s;", + (if_exists ? "IF EXISTS " : ""), + fmtIdEnc(dbname, PQclientEncoding(conn)), + force ? " WITH (FORCE)" : ""); + if (echo) printf("%s\n", sql.data); result = PQexec(conn, sql.data); diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c index ef4fe4cd18d..ba613dda68c 100644 --- a/src/bin/scripts/dropuser.c +++ b/src/bin/scripts/dropuser.c @@ -143,7 +143,8 @@ main(int argc, char *argv[]) initPQExpBuffer(&sql); appendPQExpBuffer(&sql, "DROP ROLE %s%s;", - (if_exists ? "IF EXISTS " : ""), fmtId(dropuser)); + (if_exists ? "IF EXISTS " : ""), + fmtIdEnc(dropuser, PQclientEncoding(conn))); if (echo) printf("%s\n", sql.data); diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c index 8e7fa276549..d7813b18fd3 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -532,7 +532,8 @@ run_reindex_command(PGconn *conn, ReindexType type, const char *name, { case REINDEX_DATABASE: case REINDEX_SYSTEM: - appendPQExpBufferStr(&sql, fmtId(name)); + appendPQExpBufferStr(&sql, + fmtIdEnc(name, PQclientEncoding(conn))); break; case REINDEX_INDEX: case REINDEX_TABLE: @@ -702,8 +703,9 @@ get_parallel_object_list(PGconn *conn, ReindexType type, for (i = 0; i < ntups; i++) { appendPQExpBufferStr(&buf, - fmtQualifiedId(PQgetvalue(res, i, 1), - PQgetvalue(res, i, 0))); + fmtQualifiedIdEnc(PQgetvalue(res, i, 1), + PQgetvalue(res, i, 0), + PQclientEncoding(conn))); simple_string_list_append(tables, buf.data); resetPQExpBuffer(&buf); diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index a46fb7133b7..55c24a4db9a 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -611,8 +611,9 @@ vacuum_one_database(const ConnParams *cparams, for (i = 0; i < ntups; i++) { appendPQExpBufferStr(&buf, - fmtQualifiedId(PQgetvalue(res, i, 1), - PQgetvalue(res, i, 0))); + fmtQualifiedIdEnc(PQgetvalue(res, i, 1), + PQgetvalue(res, i, 0), + PQclientEncoding(conn))); if (tables_listed && !PQgetisnull(res, i, 2)) appendPQExpBufferStr(&buf, PQgetvalue(res, i, 2)); |
