]> granicus.if.org Git - postgresql/blobdiff - src/bin/psql/variables.c
psql: fix \connect with URIs and conninfo strings
[postgresql] / src / bin / psql / variables.c
index 7d80b4abe9831191e41a0aa23c5f47fa79b84e76..b9a3dfad3316ec0875c4b15d46e917f71c354beb 100644 (file)
@@ -1,15 +1,45 @@
 /*
  * psql - the PostgreSQL interactive terminal
  *
- * Copyright (c) 2000-2007, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2015, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/variables.c,v 1.27 2007/01/05 22:19:50 momjian Exp $
+ * src/bin/psql/variables.c
  */
 #include "postgres_fe.h"
+
 #include "common.h"
 #include "variables.h"
 
 
+/*
+ * Check whether a variable's name is allowed.
+ *
+ * We allow any non-ASCII character, as well as ASCII letters, digits, and
+ * underscore.  Keep this in sync with the definition of variable_char in
+ * psqlscan.l.
+ */
+static bool
+valid_variable_name(const char *name)
+{
+       const unsigned char *ptr = (const unsigned char *) name;
+
+       /* Mustn't be zero-length */
+       if (*ptr == '\0')
+               return false;
+
+       while (*ptr)
+       {
+               if (IS_HIGHBIT_SET(*ptr) ||
+                       strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
+                                  "_0123456789", *ptr) != NULL)
+                       ptr++;
+               else
+                       return false;
+       }
+
+       return true;
+}
+
 /*
  * A "variable space" is represented by an otherwise-unused struct _variable
  * that serves as list header.
@@ -48,21 +78,53 @@ GetVariable(VariableSpace space, const char *name)
        return NULL;
 }
 
+/*
+ * Try to interpret "value" as boolean value.
+ *
+ * Valid values are: true, false, yes, no, on, off, 1, 0; as well as unique
+ * prefixes thereof.
+ *
+ * "name" is the name of the variable we're assigning to, to use in error
+ * report if any.  Pass name == NULL to suppress the error report.
+ */
 bool
-ParseVariableBool(const char *val)
+ParseVariableBool(const char *value, const char *name)
 {
-       if (val == NULL)
+       size_t          len;
+
+       if (value == NULL)
                return false;                   /* not set -> assume "off" */
-       if (pg_strcasecmp(val, "off") == 0)
-               return false;                   /* accept "off" or "OFF" as true */
 
-       /*
-        * for backwards compatibility, anything except "off" or "OFF" is taken as
-        * "true"
-        */
-       return true;
+       len = strlen(value);
+
+       if (pg_strncasecmp(value, "true", len) == 0)
+               return true;
+       else if (pg_strncasecmp(value, "false", len) == 0)
+               return false;
+       else if (pg_strncasecmp(value, "yes", len) == 0)
+               return true;
+       else if (pg_strncasecmp(value, "no", len) == 0)
+               return false;
+       /* 'o' is not unique enough */
+       else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
+               return true;
+       else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
+               return false;
+       else if (pg_strcasecmp(value, "1") == 0)
+               return true;
+       else if (pg_strcasecmp(value, "0") == 0)
+               return false;
+       else
+       {
+               /* NULL is treated as false, so a non-matching value is 'true' */
+               if (name)
+                       psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+                                          value, name, "on");
+               return true;
+       }
 }
 
+
 /*
  * Read numeric variable, or defaultval if it is not set, or faultval if its
  * value is not a valid numeric string.  If allowtrail is false, this will
@@ -131,7 +193,7 @@ SetVariable(VariableSpace space, const char *name, const char *value)
        if (!space)
                return false;
 
-       if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
+       if (!valid_variable_name(name))
                return false;
 
        if (!value)
@@ -175,7 +237,7 @@ SetVariableAssignHook(VariableSpace space, const char *name, VariableAssignHook
        if (!space)
                return false;
 
-       if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
+       if (!valid_variable_name(name))
                return false;
 
        for (previous = space, current = space->next;