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

Commit30b5ede

Browse files
committed
Fix escaping in generated recovery.conf file.
In the primary_conninfo line that "pg_basebackup -R" generates, singlequotes in parameter values need to be escaped into \\'; the libpq parserrequires the quotes to be escaped into \', and recovery.conf parser requiresthe \ to be escaped into \\.Also, don't quote parameter values unnecessarily, to make the connectionstring prettier. Most options in a libpq connection string don't needquoting.Reported by Hari Babu, closer analysis by Zoltan Boszormenyi, although Ididn't use his patch.
1 parent2af0971 commit30b5ede

File tree

1 file changed

+89
-12
lines changed

1 file changed

+89
-12
lines changed

‎src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,71 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
11071107
}
11081108

11091109
/*
1110-
* Escape single quotes used in connection parameters
1110+
* Escape a parameter value so that it can be used as part of a libpq
1111+
* connection string, e.g. in:
1112+
*
1113+
* application_name=<value>
1114+
*
1115+
* The returned string is malloc'd. Return NULL on out-of-memory.
1116+
*/
1117+
staticchar*
1118+
escapeConnectionParameter(constchar*src)
1119+
{
1120+
boolneed_quotes= false;
1121+
boolneed_escaping= false;
1122+
constchar*p;
1123+
char*dstbuf;
1124+
char*dst;
1125+
1126+
/*
1127+
* First check if quoting is needed. Any quote (') or backslash (\)
1128+
* characters need to be escaped. Parameters are separated by whitespace,
1129+
* so any string containing whitespace characters need to be quoted. An
1130+
* empty string is represented by ''.
1131+
*/
1132+
if (strchr(src,'\'')!=NULL||strchr(src,'\\')!=NULL)
1133+
need_escaping= true;
1134+
1135+
for (p=src;*p;p++)
1136+
{
1137+
if (isspace(*p))
1138+
{
1139+
need_quotes= true;
1140+
break;
1141+
}
1142+
}
1143+
1144+
if (*src=='\0')
1145+
returnpg_strdup("''");
1146+
1147+
if (!need_quotes&& !need_escaping)
1148+
returnpg_strdup(src);/* no quoting or escaping needed */
1149+
1150+
/*
1151+
* Allocate a buffer large enough for the worst case that all the source
1152+
* characters need to be escaped, plus quotes.
1153+
*/
1154+
dstbuf=pg_malloc(strlen(src)*2+2+1);
1155+
1156+
dst=dstbuf;
1157+
if (need_quotes)
1158+
*(dst++)='\'';
1159+
for (;*src;src++)
1160+
{
1161+
if (*src=='\''||*src=='\\')
1162+
*(dst++)='\\';
1163+
*(dst++)=*src;
1164+
}
1165+
if (need_quotes)
1166+
*(dst++)='\'';
1167+
*dst='\0';
1168+
1169+
returndstbuf;
1170+
}
1171+
1172+
/*
1173+
* Escape a string so that it can be used as a value in a key-value pair
1174+
* a configuration file.
11111175
*/
11121176
staticchar*
11131177
escape_quotes(constchar*src)
@@ -1130,6 +1194,8 @@ GenerateRecoveryConf(PGconn *conn)
11301194
{
11311195
PQconninfoOption*connOptions;
11321196
PQconninfoOption*option;
1197+
PQExpBufferDataconninfo_buf;
1198+
char*escaped;
11331199

11341200
recoveryconfcontents=createPQExpBuffer();
11351201
if (!recoveryconfcontents)
@@ -1146,12 +1212,10 @@ GenerateRecoveryConf(PGconn *conn)
11461212
}
11471213

11481214
appendPQExpBufferStr(recoveryconfcontents,"standby_mode = 'on'\n");
1149-
appendPQExpBufferStr(recoveryconfcontents,"primary_conninfo = '");
11501215

1216+
initPQExpBuffer(&conninfo_buf);
11511217
for (option=connOptions;option&&option->keyword;option++)
11521218
{
1153-
char*escaped;
1154-
11551219
/*
11561220
* Do not emit this setting if: - the setting is "replication",
11571221
* "dbname" or "fallback_application_name", since these would be
@@ -1165,24 +1229,37 @@ GenerateRecoveryConf(PGconn *conn)
11651229
(option->val!=NULL&&option->val[0]=='\0'))
11661230
continue;
11671231

1232+
/* Separate key-value pairs with spaces */
1233+
if (conninfo_buf.len!=0)
1234+
appendPQExpBufferStr(&conninfo_buf," ");
1235+
11681236
/*
1169-
* Write "keyword='value'" pieces, the value string is escapedif
1170-
*necessary and doubled single quotes around the value string.
1237+
* Write "keyword=value" pieces, the value string is escapedand/or
1238+
*quoted if necessary.
11711239
*/
1172-
escaped=escape_quotes(option->val);
1173-
1174-
appendPQExpBuffer(recoveryconfcontents,"%s=''%s'' ",option->keyword,escaped);
1175-
1240+
escaped=escapeConnectionParameter(option->val);
1241+
appendPQExpBuffer(&conninfo_buf,"%s=%s",option->keyword,escaped);
11761242
free(escaped);
11771243
}
11781244

1179-
appendPQExpBufferStr(recoveryconfcontents,"'\n");
1180-
if (PQExpBufferBroken(recoveryconfcontents))
1245+
/*
1246+
* Escape the connection string, so that it can be put in the config file.
1247+
* Note that this is different from the escaping of individual connection
1248+
* options above!
1249+
*/
1250+
escaped=escape_quotes(conninfo_buf.data);
1251+
appendPQExpBuffer(recoveryconfcontents,"primary_conninfo = '%s'\n",escaped);
1252+
free(escaped);
1253+
1254+
if (PQExpBufferBroken(recoveryconfcontents)||
1255+
PQExpBufferDataBroken(conninfo_buf))
11811256
{
11821257
fprintf(stderr,_("%s: out of memory\n"),progname);
11831258
disconnect_and_exit(1);
11841259
}
11851260

1261+
termPQExpBuffer(&conninfo_buf);
1262+
11861263
PQconninfoFree(connOptions);
11871264
}
11881265

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp