@@ -83,6 +83,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
83
83
static void _getObjectDescription (PQExpBuffer buf , TocEntry * te ,
84
84
ArchiveHandle * AH );
85
85
static void _printTocEntry (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt , bool isData , bool acl_pass );
86
+ static char * replace_line_endings (const char * str );
86
87
87
88
88
89
static void _doSetFixedOutputState (ArchiveHandle * AH );
@@ -2803,6 +2804,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2803
2804
if (!AH -> noTocComments )
2804
2805
{
2805
2806
const char * pfx ;
2807
+ char * sanitized_name ;
2808
+ char * sanitized_schema ;
2809
+ char * sanitized_owner ;
2806
2810
2807
2811
if (isData )
2808
2812
pfx = "Data for " ;
@@ -2824,12 +2828,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2824
2828
ahprintf (AH , "\n" );
2825
2829
}
2826
2830
}
2831
+
2832
+ /*
2833
+ * Zap any line endings embedded in user-supplied fields, to prevent
2834
+ * corruption of the dump (which could, in the worst case, present an
2835
+ * SQL injection vulnerability if someone were to incautiously load a
2836
+ * dump containing objects with maliciously crafted names).
2837
+ */
2838
+ sanitized_name = replace_line_endings (te -> tag );
2839
+ if (te -> namespace )
2840
+ sanitized_schema = replace_line_endings (te -> namespace );
2841
+ else
2842
+ sanitized_schema = strdup ("-" );
2843
+ if (!ropt -> noOwner )
2844
+ sanitized_owner = replace_line_endings (te -> owner );
2845
+ else
2846
+ sanitized_owner = strdup ("-" );
2847
+
2827
2848
ahprintf (AH , "-- %sName: %s; Type: %s; Schema: %s; Owner: %s" ,
2828
- pfx , te -> tag , te -> desc ,
2829
- te -> namespace ? te -> namespace : "-" ,
2830
- ropt -> noOwner ? "-" : te -> owner );
2849
+ pfx , sanitized_name , te -> desc , sanitized_schema ,
2850
+ sanitized_owner );
2851
+
2852
+ free (sanitized_name );
2853
+ free (sanitized_schema );
2854
+ free (sanitized_owner );
2855
+
2831
2856
if (te -> tablespace && !ropt -> noTablespace )
2832
- ahprintf (AH , "; Tablespace: %s" , te -> tablespace );
2857
+ {
2858
+ char * sanitized_tablespace ;
2859
+
2860
+ sanitized_tablespace = replace_line_endings (te -> tablespace );
2861
+ ahprintf (AH , "; Tablespace: %s" , sanitized_tablespace );
2862
+ free (sanitized_tablespace );
2863
+ }
2833
2864
ahprintf (AH , "\n" );
2834
2865
2835
2866
if (AH -> PrintExtraTocPtr != NULL )
@@ -2921,6 +2952,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2921
2952
}
2922
2953
}
2923
2954
2955
+ /*
2956
+ * Sanitize a string to be included in an SQL comment, by replacing any
2957
+ * newlines with spaces.
2958
+ */
2959
+ static char *
2960
+ replace_line_endings (const char * str )
2961
+ {
2962
+ char * result ;
2963
+ char * s ;
2964
+
2965
+ result = strdup (str );
2966
+
2967
+ for (s = result ; * s != '\0' ; s ++ )
2968
+ {
2969
+ if (* s == '\n' || * s == '\r' )
2970
+ * s = ' ' ;
2971
+ }
2972
+
2973
+ return result ;
2974
+ }
2975
+
2924
2976
void
2925
2977
WriteHead (ArchiveHandle * AH )
2926
2978
{
0 commit comments