v20-0001-pg_dumpall-deal-witth-newline-or-carriage-ret.no-cfbot
application/octet-stream
Filename: v20-0001-pg_dumpall-deal-witth-newline-or-carriage-ret.no-cfbot
Type: application/octet-stream
Part: 0
Message:
Re: Non-text mode for pg_dumpall
From bf0db3afb9cb7d34033fe500315be8033efff49e Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
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