Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit41f18f0

Browse files
committed
Promote pg_dumpall shell/connstr quoting functions to src/fe_utils.
Rename these newly-extern functions with terms more typical of their newneighbors. No functional changes; a subsequent commit will use them inmore places. Back-patch to 9.1 (all supported versions). Back brancheslack src/fe_utils, so instead rename the functions in place; thesubsequent commit will copy them into the other programs using them.Security:CVE-2016-5424
1 parentbd65371 commit41f18f0

File tree

4 files changed

+157
-154
lines changed

4 files changed

+157
-154
lines changed

‎src/bin/pg_dump/pg_dumpall.c

Lines changed: 7 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
5050
constchar*name2);
5151
staticvoiddumpDatabases(PGconn*conn);
5252
staticvoiddumpTimestamp(constchar*msg);
53-
staticvoiddoShellQuoting(PQExpBufferbuf,constchar*str);
54-
staticvoiddoConnStrQuoting(PQExpBufferbuf,constchar*str);
5553

5654
staticintrunPgDump(constchar*dbname);
5755
staticvoidbuildShSecLabels(PGconn*conn,constchar*catalog_name,
@@ -215,7 +213,7 @@ main(int argc, char *argv[])
215213
case'f':
216214
filename=pg_strdup(optarg);
217215
appendPQExpBufferStr(pgdumpopts," -f ");
218-
doShellQuoting(pgdumpopts,filename);
216+
appendShellString(pgdumpopts,filename);
219217
break;
220218

221219
case'g':
@@ -252,7 +250,7 @@ main(int argc, char *argv[])
252250

253251
case'S':
254252
appendPQExpBufferStr(pgdumpopts," -S ");
255-
doShellQuoting(pgdumpopts,optarg);
253+
appendShellString(pgdumpopts,optarg);
256254
break;
257255

258256
case't':
@@ -288,13 +286,13 @@ main(int argc, char *argv[])
288286

289287
case2:
290288
appendPQExpBufferStr(pgdumpopts," --lock-wait-timeout ");
291-
doShellQuoting(pgdumpopts,optarg);
289+
appendShellString(pgdumpopts,optarg);
292290
break;
293291

294292
case3:
295293
use_role=pg_strdup(optarg);
296294
appendPQExpBufferStr(pgdumpopts," --role ");
297-
doShellQuoting(pgdumpopts,use_role);
295+
appendShellString(pgdumpopts,use_role);
298296
break;
299297

300298
default:
@@ -1814,9 +1812,9 @@ runPgDump(const char *dbname)
18141812
* string.
18151813
*/
18161814
appendPQExpBuffer(connstrbuf,"%s dbname=",connstr);
1817-
doConnStrQuoting(connstrbuf,dbname);
1815+
appendConnStrVal(connstrbuf,dbname);
18181816

1819-
doShellQuoting(cmd,connstrbuf->data);
1817+
appendShellString(cmd,connstrbuf->data);
18201818

18211819
if (verbose)
18221820
fprintf(stderr,_("%s: running \"%s\"\n"),progname,cmd->data);
@@ -2096,7 +2094,7 @@ constructConnStr(const char **keywords, const char **values)
20962094
appendPQExpBufferChar(buf,' ');
20972095
firstkeyword= false;
20982096
appendPQExpBuffer(buf,"%s=",keywords[i]);
2099-
doConnStrQuoting(buf,values[i]);
2097+
appendConnStrVal(buf,values[i]);
21002098
}
21012099

21022100
connstr=pg_strdup(buf->data);
@@ -2169,145 +2167,3 @@ dumpTimestamp(const char *msg)
21692167
if (strftime(buf,sizeof(buf),PGDUMP_STRFTIME_FMT,localtime(&now))!=0)
21702168
fprintf(OPF,"-- %s %s\n\n",msg,buf);
21712169
}
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-
staticvoid
2180-
doConnStrQuoting(PQExpBufferbuf,constchar*str)
2181-
{
2182-
constchar*s;
2183-
boolneedquotes;
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-
staticvoid
2229-
doShellQuoting(PQExpBufferbuf,constchar*str)
2230-
{
2231-
constchar*p;
2232-
2233-
#ifndefWIN32
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-
intbackslash_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-
elseif (*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-
}

‎src/fe_utils/string_utils.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,149 @@ appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length,
378378
}
379379

380380

381+
/*
382+
* Append the given string to the shell command being built in the buffer,
383+
* with suitable shell-style quoting to create exactly one argument.
384+
*
385+
* Forbid LF or CR characters, which have scant practical use beyond designing
386+
* security breaches. The Windows command shell is unusable as a conduit for
387+
* arguments containing LF or CR characters. A future major release should
388+
* reject those characters in CREATE ROLE and CREATE DATABASE, because use
389+
* there eventually leads to errors here.
390+
*/
391+
void
392+
appendShellString(PQExpBufferbuf,constchar*str)
393+
{
394+
constchar*p;
395+
396+
#ifndefWIN32
397+
appendPQExpBufferChar(buf,'\'');
398+
for (p=str;*p;p++)
399+
{
400+
if (*p=='\n'||*p=='\r')
401+
{
402+
fprintf(stderr,
403+
_("shell command argument contains a newline or carriage return: \"%s\"\n"),
404+
str);
405+
exit(EXIT_FAILURE);
406+
}
407+
408+
if (*p=='\'')
409+
appendPQExpBufferStr(buf,"'\"'\"'");
410+
else
411+
appendPQExpBufferChar(buf,*p);
412+
}
413+
appendPQExpBufferChar(buf,'\'');
414+
#else/* WIN32 */
415+
intbackslash_run_length=0;
416+
417+
/*
418+
* A Windows system() argument experiences two layers of interpretation.
419+
* First, cmd.exe interprets the string. Its behavior is undocumented,
420+
* but a caret escapes any byte except LF or CR that would otherwise have
421+
* special meaning. Handling of a caret before LF or CR differs between
422+
* "cmd.exe /c" and other modes, and it is unusable here.
423+
*
424+
* Second, the new process parses its command line to construct argv (see
425+
* https://msdn.microsoft.com/en-us/library/17w5ykft.aspx). This treats
426+
* backslash-double quote sequences specially.
427+
*/
428+
appendPQExpBufferStr(buf,"^\"");
429+
for (p=str;*p;p++)
430+
{
431+
if (*p=='\n'||*p=='\r')
432+
{
433+
fprintf(stderr,
434+
_("shell command argument contains a newline or carriage return: \"%s\"\n"),
435+
str);
436+
exit(EXIT_FAILURE);
437+
}
438+
439+
/* Change N backslashes before a double quote to 2N+1 backslashes. */
440+
if (*p=='"')
441+
{
442+
while (backslash_run_length)
443+
{
444+
appendPQExpBufferStr(buf,"^\\");
445+
backslash_run_length--;
446+
}
447+
appendPQExpBufferStr(buf,"^\\");
448+
}
449+
elseif (*p=='\\')
450+
backslash_run_length++;
451+
else
452+
backslash_run_length=0;
453+
454+
/*
455+
* Decline to caret-escape the most mundane characters, to ease
456+
* debugging and lest we approach the command length limit.
457+
*/
458+
if (!((*p >='a'&&*p <='z')||
459+
(*p >='A'&&*p <='Z')||
460+
(*p >='0'&&*p <='9')))
461+
appendPQExpBufferChar(buf,'^');
462+
appendPQExpBufferChar(buf,*p);
463+
}
464+
465+
/*
466+
* Change N backslashes at end of argument to 2N backslashes, because they
467+
* precede the double quote that terminates the argument.
468+
*/
469+
while (backslash_run_length)
470+
{
471+
appendPQExpBufferStr(buf,"^\\");
472+
backslash_run_length--;
473+
}
474+
appendPQExpBufferStr(buf,"^\"");
475+
#endif/* WIN32 */
476+
}
477+
478+
479+
/*
480+
* Append the given string to the buffer, with suitable quoting for passing
481+
* the string as a value, in a keyword/pair value in a libpq connection
482+
* string
483+
*/
484+
void
485+
appendConnStrVal(PQExpBufferbuf,constchar*str)
486+
{
487+
constchar*s;
488+
boolneedquotes;
489+
490+
/*
491+
* If the string consists entirely of plain ASCII characters, no need to
492+
* quote it. This is quite conservative, but better safe than sorry.
493+
*/
494+
needquotes= false;
495+
for (s=str;*s;s++)
496+
{
497+
if (!((*s >='a'&&*s <='z')|| (*s >='A'&&*s <='Z')||
498+
(*s >='0'&&*s <='9')||*s=='_'||*s=='.'))
499+
{
500+
needquotes= true;
501+
break;
502+
}
503+
}
504+
505+
if (needquotes)
506+
{
507+
appendPQExpBufferChar(buf,'\'');
508+
while (*str)
509+
{
510+
/* ' and \ must be escaped by to \' and \\ */
511+
if (*str=='\''||*str=='\\')
512+
appendPQExpBufferChar(buf,'\\');
513+
514+
appendPQExpBufferChar(buf,*str);
515+
str++;
516+
}
517+
appendPQExpBufferChar(buf,'\'');
518+
}
519+
else
520+
appendPQExpBufferStr(buf,str);
521+
}
522+
523+
381524
/*
382525
* Deconstruct the text representation of a 1-dimensional Postgres array
383526
* into individual items.

‎src/include/fe_utils/string_utils.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
*
33
* String-processing utility routines for frontend code
44
*
5-
*Assorted utilityfunctions thatare useful in constructing SQL queries
6-
*and interpreting backend output.
5+
*Utilityfunctions thatinterpret backend output or quote strings for
6+
*assorted contexts.
77
*
88
*
99
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
@@ -40,6 +40,9 @@ extern void appendByteaLiteral(PQExpBuffer buf,
4040
constunsignedchar*str,size_tlength,
4141
boolstd_strings);
4242

43+
externvoidappendShellString(PQExpBufferbuf,constchar*str);
44+
externvoidappendConnStrVal(PQExpBufferbuf,constchar*str);
45+
4346
externboolparsePGArray(constchar*atext,char***itemarray,int*nitems);
4447

4548
externboolappendReloptionsArray(PQExpBufferbuffer,constchar*reloptions,

‎src/port/system.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*Win32 needs double quotes at the beginning and end of system()
88
*strings. If not, it gets confused with multiple quoted strings.
99
*It also requires double-quotes around the executable name and
10-
*any files used for redirection. Other args can use single-quotes.
10+
*any files used for redirection. Filter other args through
11+
*appendShellString() to quote them.
1112
*
1213
*Generated using Win32 "CMD /?":
1314
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp