bool OK = true;
FILE *fp;
+ /*
+ * Reject file name that is all-blank (including empty), as that leads to
+ * confusion --- we'd try to read the containing directory as a file.
+ */
+ if (strspn(config_file, " \t\r\n") == strlen(config_file))
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("empty configuration file name: \"%s\"",
+ config_file)));
+ record_config_file_error("empty configuration file name",
+ calling_file, calling_lineno,
+ head_p, tail_p);
+ return false;
+ }
+
/*
* Reject too-deep include nesting depth. This is just a safety check to
* avoid dumping core due to stack overflow if an include file loops back
}
abs_path = AbsoluteConfigLocation(config_file, calling_file);
+
+ /*
+ * Reject direct recursion. Indirect recursion is also possible, but it's
+ * harder to detect and so doesn't seem worth the trouble. (We test at
+ * this step because the canonicalization done by AbsoluteConfigLocation
+ * makes it more likely that a simple strcmp comparison will match.)
+ */
+ if (calling_file && strcmp(abs_path, calling_file) == 0)
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("configuration file recursion in \"%s\"",
+ calling_file)));
+ record_config_file_error("configuration file recursion",
+ calling_file, calling_lineno,
+ head_p, tail_p);
+ pfree(abs_path);
+ return false;
+ }
+
fp = AllocateFile(abs_path, "r");
if (!fp)
{
int size_filenames;
bool status;
+ /*
+ * Reject directory name that is all-blank (including empty), as that
+ * leads to confusion --- we'd read the containing directory, typically
+ * resulting in recursive inclusion of the same file(s).
+ */
+ if (strspn(includedir, " \t\r\n") == strlen(includedir))
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("empty configuration directory name: \"%s\"",
+ includedir)));
+ record_config_file_error("empty configuration directory name",
+ calling_file, calling_lineno,
+ head_p, tail_p);
+ return false;
+ }
+
+ /*
+ * We don't check for recursion or too-deep nesting depth here; the
+ * subsequent calls to ParseConfigFile will take care of that.
+ */
+
directory = AbsoluteConfigLocation(includedir, calling_file);
d = AllocateDir(directory);
if (d == NULL)
#------------------------------------------------------------------------------
# These options allow settings to be loaded from files other than the
-# default postgresql.conf.
+# default postgresql.conf. Note that these are directives, not variable
+# assignments, so they can usefully be given more than once.
-#include_dir = '' # include files ending in '.conf' from
+#include_dir = '...' # include files ending in '.conf' from
# a directory, e.g., 'conf.d'
-#include_if_exists = '' # include file only if it exists
-#include = '' # include file
+#include_if_exists = '...' # include file only if it exists
+#include = '...' # include file
#------------------------------------------------------------------------------