summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2021-01-13 19:52:49 +0000
committerTom Lane2021-01-13 19:52:59 +0000
commitc21ea4d53e9404279273da800daa49b7b9a5e81e (patch)
tree7880d8a335ed970459d48064deac74f30b29184f
parent5abca4b1cd7193d6a5c8235c97eb240312190bcb (diff)
Disallow a digit as the first character of a variable name in pgbench.
The point of this restriction is to avoid trying to substitute variables into timestamp literal values, which may contain strings like '12:34'. There is a good deal more that should be done to reduce pgbench's tendency to substitute where it shouldn't. But this is sufficient to solve the case complained of by Jaime Soler, and it's simple enough to back-patch. Back-patch to v11; before commit 9d36a3866, pgbench had a slightly different definition of what a variable name is, and anyway it seems unwise to change long-stable branches for this. Fabien Coelho Discussion: https://postgr.es/m/alpine.DEB.2.22.394.2006291740420.805678@pseudo
-rw-r--r--doc/src/sgml/ref/pgbench.sgml2
-rw-r--r--src/bin/pgbench/pgbench.c32
2 files changed, 24 insertions, 10 deletions
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index b03d0cc50f5..faa7c26b0a1 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -1008,7 +1008,7 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
<para>
There is a simple variable-substitution facility for script files.
Variable names must consist of letters (including non-Latin letters),
- digits, and underscores.
+ digits, and underscores, with the first character not being a digit.
Variables can be set by the command-line <option>-D</option> option,
explained above, or by the meta commands explained below.
In addition to any variables preset by <option>-D</option> command-line options,
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 99b06a5e050..f7da3e1f626 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1375,6 +1375,7 @@ makeVariableValue(Variable *var)
* "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
*
* Note: this static function is copied from "src/bin/psql/variables.c"
+ * but changed to disallow variable names starting with a digit.
*/
static bool
valid_variable_name(const char *name)
@@ -1385,6 +1386,15 @@ valid_variable_name(const char *name)
if (*ptr == '\0')
return false;
+ /* must not start with [0-9] */
+ if (IS_HIGHBIT_SET(*ptr) ||
+ strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
+ "_", *ptr) != NULL)
+ ptr++;
+ else
+ return false;
+
+ /* remaining characters can include [0-9] */
while (*ptr)
{
if (IS_HIGHBIT_SET(*ptr) ||
@@ -1505,23 +1515,27 @@ putVariableInt(CState *st, const char *context, char *name, int64 value)
*
* "sql" points at a colon. If what follows it looks like a valid
* variable name, return a malloc'd string containing the variable name,
- * and set *eaten to the number of characters consumed.
+ * and set *eaten to the number of characters consumed (including the colon).
* Otherwise, return NULL.
*/
static char *
parseVariable(const char *sql, int *eaten)
{
- int i = 0;
+ int i = 1; /* starting at 1 skips the colon */
char *name;
- do
- {
+ /* keep this logic in sync with valid_variable_name() */
+ if (IS_HIGHBIT_SET(sql[i]) ||
+ strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
+ "_", sql[i]) != NULL)
+ i++;
+ else
+ return NULL;
+
+ while (IS_HIGHBIT_SET(sql[i]) ||
+ strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
+ "_0123456789", sql[i]) != NULL)
i++;
- } while (IS_HIGHBIT_SET(sql[i]) ||
- strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
- "_0123456789", sql[i]) != NULL);
- if (i == 1)
- return NULL; /* no valid variable name chars */
name = pg_malloc(i);
memcpy(name, &sql[1], i - 1);