From bf0db3afb9cb7d34033fe500315be8033efff49e Mon Sep 17 00:00:00 2001 From: jian he Date: Mon, 10 Mar 2025 15:27:32 +0800 Subject: [PATCH v20 1/1] pg_dumpall deal witth newline or carriage return pg_dumpall: fail earlier if any database name contain new line. we may also need deal with role name have newline or carriage return. also see comments in appendShellString. --- src/bin/pg_dump/common_dumpall_restore.c | 18 ++++++++++++++++++ src/bin/pg_dump/common_dumpall_restore.h | 2 ++ src/bin/pg_dump/pg_dumpall.c | 13 +++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/bin/pg_dump/common_dumpall_restore.c b/src/bin/pg_dump/common_dumpall_restore.c index 92f52b7239a..4e81142373f 100644 --- a/src/bin/pg_dump/common_dumpall_restore.c +++ b/src/bin/pg_dump/common_dumpall_restore.c @@ -287,3 +287,21 @@ executeQuery(PGconn *conn, const char *query) return res; } + +/* + * append str to buf, exit if string contain newline or carriage return +*/ +void +string_contain_lfcr(PQExpBuffer buf, const char *str, const char *kind) +{ + Assert(kind != NULL); + if (!appendShellStringNoError(buf, str)) + { + + pg_log_error("%s contains a newline or carriage return: \"%s\"", kind, str); + pg_log_error_hint("If you want to dump data on \"%s\", " + "you may need rename it to make sure it does contain newline or carriage return", + str); + exit_nicely(1); + } +} diff --git a/src/bin/pg_dump/common_dumpall_restore.h b/src/bin/pg_dump/common_dumpall_restore.h index 7fe1c00ab71..c458abd0eef 100644 --- a/src/bin/pg_dump/common_dumpall_restore.h +++ b/src/bin/pg_dump/common_dumpall_restore.h @@ -15,10 +15,12 @@ #define COMMON_DUMPALL_RESTORE_H #include "pg_backup.h" +#include "pqexpbuffer.h" extern PGconn *connectDatabase(const char *dbname, const char *connection_string, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error, const char *progname, const char **connstr, int *server_version); extern PGresult *executeQuery(PGconn *conn, const char *query); +extern void string_contain_lfcr(PQExpBuffer buf, const char *str, const char *kind); #endif /* COMMON_DUMPALL_RESTORE_H */ diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 0752c44896f..f6614ce3bc2 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -1601,6 +1601,7 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) char db_subdir[MAXPGPATH]; char dbfilepath[MAXPGPATH]; FILE *map_file = NULL; + PQExpBufferData test_dbname; /* * Skip databases marked not datallowconn, since we'd be unable to connect @@ -1622,6 +1623,18 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) if (PQntuples(res) > 0) fprintf(OPF, "--\n-- Databases\n--\n\n"); + /* + * exit earlier if database name contain newline or carriage return. + * also see appendShellString comments. + */ + initPQExpBuffer(&test_dbname); + for (i = 0; i < PQntuples(res); i++) + { + char *dbname = PQgetvalue(res, i, 0); + string_contain_lfcr(&test_dbname, dbname, "database name"); + } + termPQExpBuffer(&test_dbname); + /* * If directory/tar/custom format is specified then create a subdirectory * under the main directory and each database dump file subdirectory will -- 2.34.1