Skip to content

Commit e760971

Browse files
committed
Disallow "=" in names of reloptions and foreign-data options.
We store values for these options as array elements with the syntax "name=value", hence a name containing "=" confuses matters when it's time to read the array back in. Since validation of the options is often done (long) after this conversion to array format, that leads to confusing and off-point error messages. We can improve matters by rejecting names containing "=" up-front. (Probably a better design would have involved pairs of array elements, but it's too late now --- and anyway, there's no evident use-case for option names like this. We already reject such names in some other contexts such as GUCs.) Reported-by: Chapman Flack <jcflack@acm.org> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Chapman Flack <jcflack@acm.org> Discussion: https://postgr.es/m/6830EB30.8090904@acm.org Backpatch-through: 13
1 parent b898bb2 commit e760971

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

contrib/file_fdw/expected/file_fdw.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ SET ROLE regress_file_fdw_superuser;
4848
CREATE USER MAPPING FOR regress_file_fdw_superuser SERVER file_server;
4949
CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server;
5050
-- validator tests
51+
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (foo 'bar'); -- ERROR
52+
ERROR: invalid option "foo"
53+
HINT: Valid options in this context are: filename, program, format, header, delimiter, quote, escape, null, encoding
54+
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS ("a=b" 'true'); -- ERROR
55+
ERROR: invalid option name "a=b": must not contain "="
5156
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR
5257
ERROR: COPY format "xml" not recognized
5358
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR

contrib/file_fdw/sql/file_fdw.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ CREATE USER MAPPING FOR regress_file_fdw_superuser SERVER file_server;
5555
CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server;
5656

5757
-- validator tests
58+
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (foo 'bar'); -- ERROR
59+
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS ("a=b" 'true'); -- ERROR
5860
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR
5961
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR
6062
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR

src/backend/access/common/reloptions.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,8 +1235,9 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
12351235
}
12361236
else
12371237
{
1238-
text *t;
1238+
const char *name;
12391239
const char *value;
1240+
text *t;
12401241
Size len;
12411242

12421243
/*
@@ -1283,19 +1284,27 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
12831284
* have just "name", assume "name=true" is meant. Note: the
12841285
* namespace is not output.
12851286
*/
1287+
name = def->defname;
12861288
if (def->arg != NULL)
12871289
value = defGetString(def);
12881290
else
12891291
value = "true";
12901292

1293+
/* Insist that name not contain "=", else "a=b=c" is ambiguous */
1294+
if (strchr(name, '=') != NULL)
1295+
ereport(ERROR,
1296+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1297+
errmsg("invalid option name \"%s\": must not contain \"=\"",
1298+
name)));
1299+
12911300
/*
12921301
* This is not a great place for this test, but there's no other
12931302
* convenient place to filter the option out. As WITH (oids =
12941303
* false) will be removed someday, this seems like an acceptable
12951304
* amount of ugly.
12961305
*/
12971306
if (acceptOidsOff && def->defnamespace == NULL &&
1298-
strcmp(def->defname, "oids") == 0)
1307+
strcmp(name, "oids") == 0)
12991308
{
13001309
if (defGetBoolean(def))
13011310
ereport(ERROR,
@@ -1305,11 +1314,11 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
13051314
continue;
13061315
}
13071316

1308-
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
1317+
len = VARHDRSZ + strlen(name) + 1 + strlen(value);
13091318
/* +1 leaves room for sprintf's trailing null */
13101319
t = (text *) palloc(len + 1);
13111320
SET_VARSIZE(t, len);
1312-
sprintf(VARDATA(t), "%s=%s", def->defname, value);
1321+
sprintf(VARDATA(t), "%s=%s", name, value);
13131322

13141323
astate = accumArrayResult(astate, PointerGetDatum(t),
13151324
false, TEXTOID,

src/backend/commands/foreigncmds.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,26 @@ optionListToArray(List *options)
7171
foreach(cell, options)
7272
{
7373
DefElem *def = lfirst(cell);
74+
const char *name;
7475
const char *value;
7576
Size len;
7677
text *t;
7778

79+
name = def->defname;
7880
value = defGetString(def);
79-
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
81+
82+
/* Insist that name not contain "=", else "a=b=c" is ambiguous */
83+
if (strchr(name, '=') != NULL)
84+
ereport(ERROR,
85+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
86+
errmsg("invalid option name \"%s\": must not contain \"=\"",
87+
name)));
88+
89+
len = VARHDRSZ + strlen(name) + 1 + strlen(value);
90+
/* +1 leaves room for sprintf's trailing null */
8091
t = palloc(len + 1);
8192
SET_VARSIZE(t, len);
82-
sprintf(VARDATA(t), "%s=%s", def->defname, value);
93+
sprintf(VARDATA(t), "%s=%s", name, value);
8394

8495
astate = accumArrayResult(astate, PointerGetDatum(t),
8596
false, TEXTOID,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy