@@ -89,6 +89,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
89
89
static void _getObjectDescription (PQExpBuffer buf , TocEntry * te ,
90
90
ArchiveHandle * AH );
91
91
static void _printTocEntry (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt , bool isData , bool acl_pass );
92
+ static char * replace_line_endings (const char * str );
92
93
93
94
94
95
static void _doSetFixedOutputState (ArchiveHandle * AH );
@@ -2876,6 +2877,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2876
2877
if (!AH -> noTocComments )
2877
2878
{
2878
2879
const char * pfx ;
2880
+ char * sanitized_name ;
2881
+ char * sanitized_schema ;
2882
+ char * sanitized_owner ;
2879
2883
2880
2884
if (isData )
2881
2885
pfx = "Data for " ;
@@ -2897,12 +2901,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2897
2901
ahprintf (AH , "\n" );
2898
2902
}
2899
2903
}
2904
+
2905
+ /*
2906
+ * Zap any line endings embedded in user-supplied fields, to prevent
2907
+ * corruption of the dump (which could, in the worst case, present an
2908
+ * SQL injection vulnerability if someone were to incautiously load a
2909
+ * dump containing objects with maliciously crafted names).
2910
+ */
2911
+ sanitized_name = replace_line_endings (te -> tag );
2912
+ if (te -> namespace )
2913
+ sanitized_schema = replace_line_endings (te -> namespace );
2914
+ else
2915
+ sanitized_schema = strdup ("-" );
2916
+ if (!ropt -> noOwner )
2917
+ sanitized_owner = replace_line_endings (te -> owner );
2918
+ else
2919
+ sanitized_owner = strdup ("-" );
2920
+
2900
2921
ahprintf (AH , "-- %sName: %s; Type: %s; Schema: %s; Owner: %s" ,
2901
- pfx , te -> tag , te -> desc ,
2902
- te -> namespace ? te -> namespace : "-" ,
2903
- ropt -> noOwner ? "-" : te -> owner );
2922
+ pfx , sanitized_name , te -> desc , sanitized_schema ,
2923
+ sanitized_owner );
2924
+
2925
+ free (sanitized_name );
2926
+ free (sanitized_schema );
2927
+ free (sanitized_owner );
2928
+
2904
2929
if (te -> tablespace && !ropt -> noTablespace )
2905
- ahprintf (AH , "; Tablespace: %s" , te -> tablespace );
2930
+ {
2931
+ char * sanitized_tablespace ;
2932
+
2933
+ sanitized_tablespace = replace_line_endings (te -> tablespace );
2934
+ ahprintf (AH , "; Tablespace: %s" , sanitized_tablespace );
2935
+ free (sanitized_tablespace );
2936
+ }
2906
2937
ahprintf (AH , "\n" );
2907
2938
2908
2939
if (AH -> PrintExtraTocPtr != NULL )
@@ -2995,6 +3026,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2995
3026
}
2996
3027
}
2997
3028
3029
+ /*
3030
+ * Sanitize a string to be included in an SQL comment, by replacing any
3031
+ * newlines with spaces.
3032
+ */
3033
+ static char *
3034
+ replace_line_endings (const char * str )
3035
+ {
3036
+ char * result ;
3037
+ char * s ;
3038
+
3039
+ result = strdup (str );
3040
+
3041
+ for (s = result ; * s != '\0' ; s ++ )
3042
+ {
3043
+ if (* s == '\n' || * s == '\r' )
3044
+ * s = ' ' ;
3045
+ }
3046
+
3047
+ return result ;
3048
+ }
3049
+
2998
3050
void
2999
3051
WriteHead (ArchiveHandle * AH )
3000
3052
{
0 commit comments