Don't downcase entries within shared_preload_libraries et al.

load_libraries(), which processes the various xxx_preload_libraries GUCs,
was parsing them using SplitIdentifierString() which isn't really
appropriate for values that could be path names: it downcases unquoted
text, and it doesn't allow embedded whitespace unless quoted.
Use SplitDirectoriesString() instead.  That also allows us to simplify
load_libraries() a bit, since canonicalize_path() is now done for it.

While this definitely seems like a bug fix, it has the potential to
break configuration settings that accidentally worked before because
of the downcasing behavior.  Also, there's an easy workaround for the
bug, namely to double-quote troublesome text.  Hence, no back-patch.

QL Zhuo, tweaked a bit by me

Discussion: https://postgr.es/m/CAB-oJtxHVDc3H+Km3CjB9mY1VDzuyaVH_ZYSz7iXcRqCtb93Ew@mail.gmail.com
This commit is contained in:
Tom Lane 2017-06-20 13:02:42 -04:00
parent a2141c42f9
commit a69dfe5f40
2 changed files with 12 additions and 13 deletions

View File

@ -3347,7 +3347,9 @@ SplitIdentifierString(char *rawstring, char separator,
/* /*
* SplitDirectoriesString --- parse a string containing directory names * SplitDirectoriesString --- parse a string containing file/directory names
*
* This works fine on file names too; the function name is historical.
* *
* This is similar to SplitIdentifierString, except that the parsing * This is similar to SplitIdentifierString, except that the parsing
* rules are meant to handle pathnames instead of identifiers: there is * rules are meant to handle pathnames instead of identifiers: there is

View File

@ -1435,12 +1435,12 @@ load_libraries(const char *libraries, const char *gucname, bool restricted)
/* Need a modifiable copy of string */ /* Need a modifiable copy of string */
rawstring = pstrdup(libraries); rawstring = pstrdup(libraries);
/* Parse string into list of identifiers */ /* Parse string into list of filename paths */
if (!SplitIdentifierString(rawstring, ',', &elemlist)) if (!SplitDirectoriesString(rawstring, ',', &elemlist))
{ {
/* syntax error in list */ /* syntax error in list */
list_free_deep(elemlist);
pfree(rawstring); pfree(rawstring);
list_free(elemlist);
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid list syntax in parameter \"%s\"", errmsg("invalid list syntax in parameter \"%s\"",
@ -1450,28 +1450,25 @@ load_libraries(const char *libraries, const char *gucname, bool restricted)
foreach(l, elemlist) foreach(l, elemlist)
{ {
char *tok = (char *) lfirst(l); /* Note that filename was already canonicalized */
char *filename; char *filename = (char *) lfirst(l);
char *expanded = NULL;
filename = pstrdup(tok);
canonicalize_path(filename);
/* If restricting, insert $libdir/plugins if not mentioned already */ /* If restricting, insert $libdir/plugins if not mentioned already */
if (restricted && first_dir_separator(filename) == NULL) if (restricted && first_dir_separator(filename) == NULL)
{ {
char *expanded;
expanded = psprintf("$libdir/plugins/%s", filename); expanded = psprintf("$libdir/plugins/%s", filename);
pfree(filename);
filename = expanded; filename = expanded;
} }
load_file(filename, restricted); load_file(filename, restricted);
ereport(DEBUG1, ereport(DEBUG1,
(errmsg("loaded library \"%s\"", filename))); (errmsg("loaded library \"%s\"", filename)));
pfree(filename); if (expanded)
pfree(expanded);
} }
list_free_deep(elemlist);
pfree(rawstring); pfree(rawstring);
list_free(elemlist);
} }
/* /*