@@ -77,7 +77,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
7777static void _getObjectDescription (PQExpBuffer buf , TocEntry * te ,
7878 ArchiveHandle * 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{
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 */
37203700static 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 ++ )
0 commit comments