@@ -50,8 +50,6 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
50
50
const char * name2 );
51
51
static void dumpDatabases (PGconn * conn );
52
52
static void dumpTimestamp (const char * msg );
53
- static void doShellQuoting (PQExpBuffer buf , const char * str );
54
- static void doConnStrQuoting (PQExpBuffer buf , const char * str );
55
53
56
54
static int runPgDump (const char * dbname );
57
55
static void buildShSecLabels (PGconn * conn , const char * catalog_name ,
@@ -215,7 +213,7 @@ main(int argc, char *argv[])
215
213
case 'f' :
216
214
filename = pg_strdup (optarg );
217
215
appendPQExpBufferStr (pgdumpopts , " -f " );
218
- doShellQuoting (pgdumpopts , filename );
216
+ appendShellString (pgdumpopts , filename );
219
217
break ;
220
218
221
219
case 'g' :
@@ -252,7 +250,7 @@ main(int argc, char *argv[])
252
250
253
251
case 'S' :
254
252
appendPQExpBufferStr (pgdumpopts , " -S " );
255
- doShellQuoting (pgdumpopts , optarg );
253
+ appendShellString (pgdumpopts , optarg );
256
254
break ;
257
255
258
256
case 't' :
@@ -288,13 +286,13 @@ main(int argc, char *argv[])
288
286
289
287
case 2 :
290
288
appendPQExpBufferStr (pgdumpopts , " --lock-wait-timeout " );
291
- doShellQuoting (pgdumpopts , optarg );
289
+ appendShellString (pgdumpopts , optarg );
292
290
break ;
293
291
294
292
case 3 :
295
293
use_role = pg_strdup (optarg );
296
294
appendPQExpBufferStr (pgdumpopts , " --role " );
297
- doShellQuoting (pgdumpopts , use_role );
295
+ appendShellString (pgdumpopts , use_role );
298
296
break ;
299
297
300
298
default :
@@ -1814,9 +1812,9 @@ runPgDump(const char *dbname)
1814
1812
* string.
1815
1813
*/
1816
1814
appendPQExpBuffer (connstrbuf , "%s dbname=" , connstr );
1817
- doConnStrQuoting (connstrbuf , dbname );
1815
+ appendConnStrVal (connstrbuf , dbname );
1818
1816
1819
- doShellQuoting (cmd , connstrbuf -> data );
1817
+ appendShellString (cmd , connstrbuf -> data );
1820
1818
1821
1819
if (verbose )
1822
1820
fprintf (stderr , _ ("%s: running \"%s\"\n" ), progname , cmd -> data );
@@ -2096,7 +2094,7 @@ constructConnStr(const char **keywords, const char **values)
2096
2094
appendPQExpBufferChar (buf , ' ' );
2097
2095
firstkeyword = false;
2098
2096
appendPQExpBuffer (buf , "%s=" , keywords [i ]);
2099
- doConnStrQuoting (buf , values [i ]);
2097
+ appendConnStrVal (buf , values [i ]);
2100
2098
}
2101
2099
2102
2100
connstr = pg_strdup (buf -> data );
@@ -2169,145 +2167,3 @@ dumpTimestamp(const char *msg)
2169
2167
if (strftime (buf , sizeof (buf ), PGDUMP_STRFTIME_FMT , localtime (& now )) != 0 )
2170
2168
fprintf (OPF , "-- %s %s\n\n" , msg , buf );
2171
2169
}
2172
-
2173
-
2174
- /*
2175
- * Append the given string to the buffer, with suitable quoting for passing
2176
- * the string as a value, in a keyword/pair value in a libpq connection
2177
- * string
2178
- */
2179
- static void
2180
- doConnStrQuoting (PQExpBuffer buf , const char * str )
2181
- {
2182
- const char * s ;
2183
- bool needquotes ;
2184
-
2185
- /*
2186
- * If the string consists entirely of plain ASCII characters, no need to
2187
- * quote it. This is quite conservative, but better safe than sorry.
2188
- */
2189
- needquotes = false;
2190
- for (s = str ; * s ; s ++ )
2191
- {
2192
- if (!((* s >= 'a' && * s <= 'z' ) || (* s >= 'A' && * s <= 'Z' ) ||
2193
- (* s >= '0' && * s <= '9' ) || * s == '_' || * s == '.' ))
2194
- {
2195
- needquotes = true;
2196
- break ;
2197
- }
2198
- }
2199
-
2200
- if (needquotes )
2201
- {
2202
- appendPQExpBufferChar (buf , '\'' );
2203
- while (* str )
2204
- {
2205
- /* ' and \ must be escaped by to \' and \\ */
2206
- if (* str == '\'' || * str == '\\' )
2207
- appendPQExpBufferChar (buf , '\\' );
2208
-
2209
- appendPQExpBufferChar (buf , * str );
2210
- str ++ ;
2211
- }
2212
- appendPQExpBufferChar (buf , '\'' );
2213
- }
2214
- else
2215
- appendPQExpBufferStr (buf , str );
2216
- }
2217
-
2218
- /*
2219
- * Append the given string to the shell command being built in the buffer,
2220
- * with suitable shell-style quoting to create exactly one argument.
2221
- *
2222
- * Forbid LF or CR characters, which have scant practical use beyond designing
2223
- * security breaches. The Windows command shell is unusable as a conduit for
2224
- * arguments containing LF or CR characters. A future major release should
2225
- * reject those characters in CREATE ROLE and CREATE DATABASE, because use
2226
- * there eventually leads to errors here.
2227
- */
2228
- static void
2229
- doShellQuoting (PQExpBuffer buf , const char * str )
2230
- {
2231
- const char * p ;
2232
-
2233
- #ifndef WIN32
2234
- appendPQExpBufferChar (buf , '\'' );
2235
- for (p = str ; * p ; p ++ )
2236
- {
2237
- if (* p == '\n' || * p == '\r' )
2238
- {
2239
- fprintf (stderr ,
2240
- _ ("shell command argument contains a newline or carriage return: \"%s\"\n" ),
2241
- str );
2242
- exit (EXIT_FAILURE );
2243
- }
2244
-
2245
- if (* p == '\'' )
2246
- appendPQExpBufferStr (buf , "'\"'\"'" );
2247
- else
2248
- appendPQExpBufferChar (buf , * p );
2249
- }
2250
- appendPQExpBufferChar (buf , '\'' );
2251
- #else /* WIN32 */
2252
- int backslash_run_length = 0 ;
2253
-
2254
- /*
2255
- * A Windows system() argument experiences two layers of interpretation.
2256
- * First, cmd.exe interprets the string. Its behavior is undocumented,
2257
- * but a caret escapes any byte except LF or CR that would otherwise have
2258
- * special meaning. Handling of a caret before LF or CR differs between
2259
- * "cmd.exe /c" and other modes, and it is unusable here.
2260
- *
2261
- * Second, the new process parses its command line to construct argv (see
2262
- * https://msdn.microsoft.com/en-us/library/17w5ykft.aspx). This treats
2263
- * backslash-double quote sequences specially.
2264
- */
2265
- appendPQExpBufferStr (buf , "^\"" );
2266
- for (p = str ; * p ; p ++ )
2267
- {
2268
- if (* p == '\n' || * p == '\r' )
2269
- {
2270
- fprintf (stderr ,
2271
- _ ("shell command argument contains a newline or carriage return: \"%s\"\n" ),
2272
- str );
2273
- exit (EXIT_FAILURE );
2274
- }
2275
-
2276
- /* Change N backslashes before a double quote to 2N+1 backslashes. */
2277
- if (* p == '"' )
2278
- {
2279
- while (backslash_run_length )
2280
- {
2281
- appendPQExpBufferStr (buf , "^\\" );
2282
- backslash_run_length -- ;
2283
- }
2284
- appendPQExpBufferStr (buf , "^\\" );
2285
- }
2286
- else if (* p == '\\' )
2287
- backslash_run_length ++ ;
2288
- else
2289
- backslash_run_length = 0 ;
2290
-
2291
- /*
2292
- * Decline to caret-escape the most mundane characters, to ease
2293
- * debugging and lest we approach the command length limit.
2294
- */
2295
- if (!((* p >= 'a' && * p <= 'z' ) ||
2296
- (* p >= 'A' && * p <= 'Z' ) ||
2297
- (* p >= '0' && * p <= '9' )))
2298
- appendPQExpBufferChar (buf , '^' );
2299
- appendPQExpBufferChar (buf , * p );
2300
- }
2301
-
2302
- /*
2303
- * Change N backslashes at end of argument to 2N backslashes, because they
2304
- * precede the double quote that terminates the argument.
2305
- */
2306
- while (backslash_run_length )
2307
- {
2308
- appendPQExpBufferStr (buf , "^\\" );
2309
- backslash_run_length -- ;
2310
- }
2311
- appendPQExpBufferStr (buf , "^\"" );
2312
- #endif /* WIN32 */
2313
- }
0 commit comments