diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index b11d6cb0c402156ff692c2f74f3af9782c77018d..734373beaa5090c6781dc6e25e45df7f59500e49 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -1104,7 +1104,8 @@ PrintTOCSummary(Archive *AHX) ahprintf(AH, ";\n; Archive created at %s\n", stamp_str); ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n", - AH->archdbname, AH->tocCount, AH->compression); + replace_line_endings(AH->archdbname), + AH->tocCount, AH->compression); switch (AH->format) { @@ -1142,10 +1143,37 @@ PrintTOCSummary(Archive *AHX) curSection = te->section; if (ropt->verbose || (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0) + { + char *sanitized_name; + char *sanitized_schema; + char *sanitized_owner; + + /* + * As in _printTocEntry(), sanitize strings that might contain + * newlines, to ensure that each logical output line is in fact + * one physical output line. This prevents confusion when the + * file is read by "pg_restore -L". Note that we currently don't + * bother to quote names, meaning that the name fields aren't + * automatically parseable. "pg_restore -L" doesn't care because + * it only examines the dumpId field, but someday we might want to + * try harder. + */ + sanitized_name = replace_line_endings(te->tag); + if (te->namespace) + sanitized_schema = replace_line_endings(te->namespace); + else + sanitized_schema = pg_strdup("-"); + sanitized_owner = replace_line_endings(te->owner); + ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId, te->catalogId.tableoid, te->catalogId.oid, - te->desc, te->namespace ? te->namespace : "-", - te->tag, te->owner); + te->desc, sanitized_schema, sanitized_name, + sanitized_owner); + + free(sanitized_name); + free(sanitized_schema); + free(sanitized_owner); + } if (ropt->verbose && te->nDeps > 0) { int i; @@ -3531,8 +3559,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData, bool acl_pass) } /* - * Sanitize a string to be included in an SQL comment, by replacing any - * newlines with spaces. + * Sanitize a string to be included in an SQL comment or TOC listing, + * by replacing any newlines with spaces. + * The result is a freshly malloc'd string. */ static char * replace_line_endings(const char *str)