@@ -77,7 +77,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
7777static void _getObjectDescription (PQExpBuffer buf ,TocEntry * te ,
7878ArchiveHandle * AH );
7979static 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 );
8181static void _doSetFixedOutputState (ArchiveHandle * AH );
8282static void _doSetSessionAuth (ArchiveHandle * AH ,const char * user );
8383static void _reconnectToDB (ArchiveHandle * AH ,const char * dbname );
@@ -1066,17 +1066,8 @@ WriteData(Archive *AHX, const void *data, size_t dLen)
10661066
10671067/* Public */
10681068TocEntry *
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{
10811072ArchiveHandle * AH = (ArchiveHandle * )AHX ;
10821073TocEntry * newToc ;
@@ -1094,32 +1085,32 @@ ArchiveEntry(Archive *AHX,
10941085
10951086newToc -> catalogId = catalogId ;
10961087newToc -> 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}
11141105else
11151106{
11161107newToc -> dependencies = NULL ;
11171108newToc -> 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
11241115newToc -> formatData = NULL ;
11251116newToc -> dataLength = 0 ;
@@ -1152,7 +1143,7 @@ PrintTOCSummary(Archive *AHX)
11521143
11531144ahprintf (AH ,";\n; Archive created at %s\n" ,stamp_str );
11541145ahprintf (AH ,"; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n" ,
1155- replace_line_endings (AH -> archdbname ),
1146+ sanitize_line (AH -> archdbname , false ),
11561147AH -> tocCount ,AH -> compression );
11571148
11581149switch (AH -> format )
@@ -1197,21 +1188,10 @@ PrintTOCSummary(Archive *AHX)
11971188char * 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
12161196ahprintf (AH ,"%d; %u %u %s %s %s %s\n" ,te -> dumpId ,
12171197te -> 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
35963564ahprintf (AH ,"-- %sName: %s; Type: %s; Schema: %s; Owner: %s" ,
35973565pfx ,sanitized_name ,te -> desc ,sanitized_schema ,
@@ -3605,7 +3573,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
36053573{
36063574char * sanitized_tablespace ;
36073575
3608- sanitized_tablespace = replace_line_endings (te -> tablespace );
3576+ sanitized_tablespace = sanitize_line (te -> tablespace , false );
36093577ahprintf (AH ,"; Tablespace: %s" ,sanitized_tablespace );
36103578free (sanitized_tablespace );
36113579}
@@ -3629,7 +3597,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
36293597}
36303598else
36313599{
3632- if (strlen (te -> defn )> 0 )
3600+ if (te -> defn && strlen (te -> defn )> 0 )
36333601ahprintf (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 */
36423610if (!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{
36453614if (strcmp (te -> desc ,"AGGREGATE" )== 0 ||
36463615strcmp (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 */
37203700static char *
3721- replace_line_endings (const char * str )
3701+ sanitize_line (const char * str , bool want_hyphen )
37223702{
37233703char * result ;
37243704char * s ;
37253705
3706+ if (!str )
3707+ return pg_strdup (want_hyphen ?"-" :"" );
3708+
37263709result = pg_strdup (str );
37273710
37283711for (s = result ;* s != '\0' ;s ++ )