@@ -97,6 +97,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
97
97
static void _getObjectDescription (PQExpBuffer buf , TocEntry * te ,
98
98
ArchiveHandle * AH );
99
99
static void _printTocEntry (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt , bool isData , bool acl_pass );
100
+ static char * replace_line_endings (const char * str );
100
101
101
102
102
103
static void _doSetFixedOutputState (ArchiveHandle * AH );
@@ -2939,6 +2940,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2939
2940
if (!AH -> noTocComments )
2940
2941
{
2941
2942
const char * pfx ;
2943
+ char * sanitized_name ;
2944
+ char * sanitized_schema ;
2945
+ char * sanitized_owner ;
2942
2946
2943
2947
if (isData )
2944
2948
pfx = "Data for " ;
@@ -2960,12 +2964,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2960
2964
ahprintf (AH , "\n" );
2961
2965
}
2962
2966
}
2967
+
2968
+ /*
2969
+ * Zap any line endings embedded in user-supplied fields, to prevent
2970
+ * corruption of the dump (which could, in the worst case, present an
2971
+ * SQL injection vulnerability if someone were to incautiously load a
2972
+ * dump containing objects with maliciously crafted names).
2973
+ */
2974
+ sanitized_name = replace_line_endings (te -> tag );
2975
+ if (te -> namespace )
2976
+ sanitized_schema = replace_line_endings (te -> namespace );
2977
+ else
2978
+ sanitized_schema = strdup ("-" );
2979
+ if (!ropt -> noOwner )
2980
+ sanitized_owner = replace_line_endings (te -> owner );
2981
+ else
2982
+ sanitized_owner = strdup ("-" );
2983
+
2963
2984
ahprintf (AH , "-- %sName: %s; Type: %s; Schema: %s; Owner: %s" ,
2964
- pfx , te -> tag , te -> desc ,
2965
- te -> namespace ? te -> namespace : "-" ,
2966
- ropt -> noOwner ? "-" : te -> owner );
2985
+ pfx , sanitized_name , te -> desc , sanitized_schema ,
2986
+ sanitized_owner );
2987
+
2988
+ free (sanitized_name );
2989
+ free (sanitized_schema );
2990
+ free (sanitized_owner );
2991
+
2967
2992
if (te -> tablespace && !ropt -> noTablespace )
2968
- ahprintf (AH , "; Tablespace: %s" , te -> tablespace );
2993
+ {
2994
+ char * sanitized_tablespace ;
2995
+
2996
+ sanitized_tablespace = replace_line_endings (te -> tablespace );
2997
+ ahprintf (AH , "; Tablespace: %s" , sanitized_tablespace );
2998
+ free (sanitized_tablespace );
2999
+ }
2969
3000
ahprintf (AH , "\n" );
2970
3001
2971
3002
if (AH -> PrintExtraTocPtr != NULL )
@@ -3060,6 +3091,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
3060
3091
}
3061
3092
}
3062
3093
3094
+ /*
3095
+ * Sanitize a string to be included in an SQL comment, by replacing any
3096
+ * newlines with spaces.
3097
+ */
3098
+ static char *
3099
+ replace_line_endings (const char * str )
3100
+ {
3101
+ char * result ;
3102
+ char * s ;
3103
+
3104
+ result = strdup (str );
3105
+
3106
+ for (s = result ; * s != '\0' ; s ++ )
3107
+ {
3108
+ if (* s == '\n' || * s == '\r' )
3109
+ * s = ' ' ;
3110
+ }
3111
+
3112
+ return result ;
3113
+ }
3114
+
3063
3115
void
3064
3116
WriteHead (ArchiveHandle * AH )
3065
3117
{
0 commit comments