Skip to content

Commit f831d4a

Browse files
committed
Add ArchiveOpts to pass options to ArchiveEntry
The ArchiveEntry function has a number of arguments that can be considered optional. Split them out into a separate struct, to make the API more flexible for changes. Author: Dmitry Dolgov Discussion: https://postgr.es/m/CA+q6zcXRxPE+qp6oerQWJ3zS061WPOhdxeMrdc-Yf-2V5vsrEw@mail.gmail.com
1 parent 456e371 commit f831d4a

File tree

3 files changed

+522
-577
lines changed

3 files changed

+522
-577
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 50 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
7777
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
7878
ArchiveHandle *AH);
7979
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
80-
static char *replace_line_endings(const char *str);
80+
static char *sanitize_line(const char *str, bool want_hyphen);
8181
static void _doSetFixedOutputState(ArchiveHandle *AH);
8282
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
8383
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
@@ -1066,17 +1066,8 @@ WriteData(Archive *AHX, const void *data, size_t dLen)
10661066

10671067
/* Public */
10681068
TocEntry *
1069-
ArchiveEntry(Archive *AHX,
1070-
CatalogId catalogId, DumpId dumpId,
1071-
const char *tag,
1072-
const char *namespace,
1073-
const char *tablespace,
1074-
const char *owner,
1075-
const char *desc, teSection section,
1076-
const char *defn,
1077-
const char *dropStmt, const char *copyStmt,
1078-
const DumpId *deps, int nDeps,
1079-
DataDumperPtr dumpFn, void *dumpArg)
1069+
ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
1070+
ArchiveOpts *opts)
10801071
{
10811072
ArchiveHandle *AH = (ArchiveHandle *) AHX;
10821073
TocEntry *newToc;
@@ -1094,32 +1085,32 @@ ArchiveEntry(Archive *AHX,
10941085

10951086
newToc->catalogId = catalogId;
10961087
newToc->dumpId = dumpId;
1097-
newToc->section = section;
1098-
1099-
newToc->tag = pg_strdup(tag);
1100-
newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
1101-
newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
1102-
newToc->owner = pg_strdup(owner);
1103-
newToc->desc = pg_strdup(desc);
1104-
newToc->defn = pg_strdup(defn);
1105-
newToc->dropStmt = pg_strdup(dropStmt);
1106-
newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;
1107-
1108-
if (nDeps > 0)
1088+
newToc->section = opts->section;
1089+
1090+
newToc->tag = pg_strdup(opts->tag);
1091+
newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
1092+
newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
1093+
newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
1094+
newToc->desc = pg_strdup(opts->description);
1095+
newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
1096+
newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
1097+
newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
1098+
1099+
if (opts->nDeps > 0)
11091100
{
1110-
newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
1111-
memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
1112-
newToc->nDeps = nDeps;
1101+
newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId));
1102+
memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId));
1103+
newToc->nDeps = opts->nDeps;
11131104
}
11141105
else
11151106
{
11161107
newToc->dependencies = NULL;
11171108
newToc->nDeps = 0;
11181109
}
11191110

1120-
newToc->dataDumper = dumpFn;
1121-
newToc->dataDumperArg = dumpArg;
1122-
newToc->hadDumper = dumpFn ? true : false;
1111+
newToc->dataDumper = opts->dumpFn;
1112+
newToc->dataDumperArg = opts->dumpArg;
1113+
newToc->hadDumper = opts->dumpFn ? true : false;
11231114

11241115
newToc->formatData = NULL;
11251116
newToc->dataLength = 0;
@@ -1152,7 +1143,7 @@ PrintTOCSummary(Archive *AHX)
11521143

11531144
ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
11541145
ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1155-
replace_line_endings(AH->archdbname),
1146+
sanitize_line(AH->archdbname, false),
11561147
AH->tocCount, AH->compression);
11571148

11581149
switch (AH->format)
@@ -1197,21 +1188,10 @@ PrintTOCSummary(Archive *AHX)
11971188
char *sanitized_owner;
11981189

11991190
/*
1200-
* As in _printTocEntry(), sanitize strings that might contain
1201-
* newlines, to ensure that each logical output line is in fact
1202-
* one physical output line. This prevents confusion when the
1203-
* file is read by "pg_restore -L". Note that we currently don't
1204-
* bother to quote names, meaning that the name fields aren't
1205-
* automatically parseable. "pg_restore -L" doesn't care because
1206-
* it only examines the dumpId field, but someday we might want to
1207-
* try harder.
12081191
*/
1209-
sanitized_name = replace_line_endings(te->tag);
1210-
if (te->namespace)
1211-
sanitized_schema = replace_line_endings(te->namespace);
1212-
else
1213-
sanitized_schema = pg_strdup("-");
1214-
sanitized_owner = replace_line_endings(te->owner);
1192+
sanitized_name = sanitize_line(te->tag, false);
1193+
sanitized_schema = sanitize_line(te->namespace, true);
1194+
sanitized_owner = sanitize_line(te->owner, false);
12151195

12161196
ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
12171197
te->catalogId.tableoid, te->catalogId.oid,
@@ -3577,21 +3557,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
35773557
}
35783558
}
35793559

3580-
/*
3581-
* Zap any line endings embedded in user-supplied fields, to prevent
3582-
* corruption of the dump (which could, in the worst case, present an
3583-
* SQL injection vulnerability if someone were to incautiously load a
3584-
* dump containing objects with maliciously crafted names).
3585-
*/
3586-
sanitized_name = replace_line_endings(te->tag);
3587-
if (te->namespace)
3588-
sanitized_schema = replace_line_endings(te->namespace);
3589-
else
3590-
sanitized_schema = pg_strdup("-");
3591-
if (!ropt->noOwner)
3592-
sanitized_owner = replace_line_endings(te->owner);
3593-
else
3594-
sanitized_owner = pg_strdup("-");
3560+
sanitized_name = sanitize_line(te->tag, false);
3561+
sanitized_schema = sanitize_line(te->namespace, true);
3562+
sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
35953563

35963564
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
35973565
pfx, sanitized_name, te->desc, sanitized_schema,
@@ -3605,7 +3573,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
36053573
{
36063574
char *sanitized_tablespace;
36073575

3608-
sanitized_tablespace = replace_line_endings(te->tablespace);
3576+
sanitized_tablespace = sanitize_line(te->tablespace, false);
36093577
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
36103578
free(sanitized_tablespace);
36113579
}
@@ -3629,7 +3597,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
36293597
}
36303598
else
36313599
{
3632-
if (strlen(te->defn) > 0)
3600+
if (te->defn && strlen(te->defn) > 0)
36333601
ahprintf(AH, "%s\n\n", te->defn);
36343602
}
36353603

@@ -3640,7 +3608,8 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
36403608
* with DROP commands must appear in one list or the other.
36413609
*/
36423610
if (!ropt->noOwner && !ropt->use_setsessauth &&
3643-
strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
3611+
te->owner && strlen(te->owner) > 0 &&
3612+
te->dropStmt && strlen(te->dropStmt) > 0)
36443613
{
36453614
if (strcmp(te->desc, "AGGREGATE") == 0 ||
36463615
strcmp(te->desc, "BLOB") == 0 ||
@@ -3713,16 +3682,30 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
37133682
}
37143683

37153684
/*
3716-
* Sanitize a string to be included in an SQL comment or TOC listing,
3717-
* by replacing any newlines with spaces.
3718-
* The result is a freshly malloc'd string.
3685+
* Sanitize a string to be included in an SQL comment or TOC listing, by
3686+
* replacing any newlines with spaces. This ensures each logical output line
3687+
* is in fact one physical output line, to prevent corruption of the dump
3688+
* (which could, in the worst case, present an SQL injection vulnerability
3689+
* if someone were to incautiously load a dump containing objects with
3690+
* maliciously crafted names).
3691+
*
3692+
* The result is a freshly malloc'd string. If the input string is NULL,
3693+
* return a malloc'ed empty string, unless want_hyphen, in which case return a
3694+
* malloc'ed hyphen.
3695+
*
3696+
* Note that we currently don't bother to quote names, meaning that the name
3697+
* fields aren't automatically parseable. "pg_restore -L" doesn't care because
3698+
* it only examines the dumpId field, but someday we might want to try harder.
37193699
*/
37203700
static char *
3721-
replace_line_endings(const char *str)
3701+
sanitize_line(const char *str, bool want_hyphen)
37223702
{
37233703
char *result;
37243704
char *s;
37253705

3706+
if (!str)
3707+
return pg_strdup(want_hyphen ? "-" : "");
3708+
37263709
result = pg_strdup(str);
37273710

37283711
for (s = result; *s != '\0'; s++)

src/bin/pg_dump/pg_backup_archiver.h

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -405,17 +405,27 @@ extern void on_exit_close_archive(Archive *AHX);
405405

406406
extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) pg_attribute_printf(3, 4);
407407

408+
/* Options for ArchiveEntry */
409+
typedef struct _archiveOpts
410+
{
411+
const char *tag;
412+
const char *namespace;
413+
const char *tablespace;
414+
const char *owner;
415+
const char *description;
416+
teSection section;
417+
const char *createStmt;
418+
const char *dropStmt;
419+
const char *copyStmt;
420+
const DumpId *deps;
421+
int nDeps;
422+
DataDumperPtr dumpFn;
423+
void *dumpArg;
424+
} ArchiveOpts;
425+
#define ARCHIVE_OPTS(...) &(ArchiveOpts){__VA_ARGS__}
408426
/* Called to add a TOC entry */
409-
extern TocEntry *ArchiveEntry(Archive *AHX,
410-
CatalogId catalogId, DumpId dumpId,
411-
const char *tag,
412-
const char *namespace, const char *tablespace,
413-
const char *owner,
414-
const char *desc, teSection section,
415-
const char *defn,
416-
const char *dropStmt, const char *copyStmt,
417-
const DumpId *deps, int nDeps,
418-
DataDumperPtr dumpFn, void *dumpArg);
427+
extern TocEntry *ArchiveEntry(Archive *AHX, CatalogId catalogId,
428+
DumpId dumpId, ArchiveOpts *opts);
419429

420430
extern void WriteTOC(ArchiveHandle *AH);
421431
extern void ReadTOC(ArchiveHandle *AH);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy