Commit 660f5328 authored by Itagaki Takahiro's avatar Itagaki Takahiro

Add verification of variable names in pgbench.

Variables must consist of only alphabets, numerals and underscores.
We had allowed to set variables with invalid names, but could not
refer them in queries.

Thanks to Robert Haas for the review.
parent 90f4c2d9
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* A simple benchmark program for PostgreSQL * A simple benchmark program for PostgreSQL
* Originally written by Tatsuo Ishii and enhanced by many contributors. * Originally written by Tatsuo Ishii and enhanced by many contributors.
* *
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.94 2010/01/02 16:57:32 momjian Exp $ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.95 2010/01/06 01:12:14 itagaki Exp $
* Copyright (c) 2000-2010, PostgreSQL Global Development Group * Copyright (c) 2000-2010, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED; * ALL RIGHTS RESERVED;
* *
...@@ -431,8 +431,23 @@ getVariable(CState *st, char *name) ...@@ -431,8 +431,23 @@ getVariable(CState *st, char *name)
return NULL; return NULL;
} }
/* check whether the name consists of alphabets, numerals and underscores. */
static bool
isLegalVariableName(const char *name)
{
int i;
for (i = 0; name[i] != '\0'; i++)
{
if (!isalnum((unsigned char) name[i]) && name[i] != '_')
return false;
}
return true;
}
static int static int
putVariable(CState *st, char *name, char *value) putVariable(CState *st, const char *context, char *name, char *value)
{ {
Variable key, Variable key,
*var; *var;
...@@ -452,6 +467,16 @@ putVariable(CState *st, char *name, char *value) ...@@ -452,6 +467,16 @@ putVariable(CState *st, char *name, char *value)
{ {
Variable *newvars; Variable *newvars;
/*
* Check for the name only when declaring a new variable to avoid
* overhead.
*/
if (!isLegalVariableName(name))
{
fprintf(stderr, "%s: invalid variable name '%s'\n", context, name);
return false;
}
if (st->variables) if (st->variables)
newvars = (Variable *) realloc(st->variables, newvars = (Variable *) realloc(st->variables,
(st->nvariables + 1) * sizeof(Variable)); (st->nvariables + 1) * sizeof(Variable));
...@@ -459,7 +484,7 @@ putVariable(CState *st, char *name, char *value) ...@@ -459,7 +484,7 @@ putVariable(CState *st, char *name, char *value)
newvars = (Variable *) malloc(sizeof(Variable)); newvars = (Variable *) malloc(sizeof(Variable));
if (newvars == NULL) if (newvars == NULL)
return false; goto out_of_memory;
st->variables = newvars; st->variables = newvars;
...@@ -493,6 +518,10 @@ putVariable(CState *st, char *name, char *value) ...@@ -493,6 +518,10 @@ putVariable(CState *st, char *name, char *value)
} }
return true; return true;
out_of_memory:
fprintf(stderr, "%s: out of memory for variable '%s'\n", context, name);
return false;
} }
static char * static char *
...@@ -687,11 +716,8 @@ runShellCommand(CState *st, char *variable, char **argv, int argc) ...@@ -687,11 +716,8 @@ runShellCommand(CState *st, char *variable, char **argv, int argc)
return false; return false;
} }
snprintf(res, sizeof(res), "%d", retval); snprintf(res, sizeof(res), "%d", retval);
if (!putVariable(st, variable, res)) if (!putVariable(st, "setshell", variable, res))
{
fprintf(stderr, "%s: out of memory\n", argv[0]);
return false; return false;
}
#ifdef DEBUG #ifdef DEBUG
printf("shell parameter name: %s, value: %s\n", argv[1], res); printf("shell parameter name: %s, value: %s\n", argv[1], res);
...@@ -987,9 +1013,8 @@ top: ...@@ -987,9 +1013,8 @@ top:
#endif #endif
snprintf(res, sizeof(res), "%d", getrand(min, max)); snprintf(res, sizeof(res), "%d", getrand(min, max));
if (putVariable(st, argv[1], res) == false) if (!putVariable(st, argv[0], argv[1], res))
{ {
fprintf(stderr, "%s: out of memory\n", argv[0]);
st->ecnt++; st->ecnt++;
return true; return true;
} }
...@@ -1057,9 +1082,8 @@ top: ...@@ -1057,9 +1082,8 @@ top:
} }
} }
if (putVariable(st, argv[1], res) == false) if (!putVariable(st, argv[0], argv[1], res))
{ {
fprintf(stderr, "%s: out of memory\n", argv[0]);
st->ecnt++; st->ecnt++;
return true; return true;
} }
...@@ -1874,12 +1898,9 @@ main(int argc, char **argv) ...@@ -1874,12 +1898,9 @@ main(int argc, char **argv)
} }
*p++ = '\0'; *p++ = '\0';
if (putVariable(&state[0], optarg, p) == false) if (!putVariable(&state[0], "option", optarg, p))
{
fprintf(stderr, "Couldn't allocate memory for variable\n");
exit(1); exit(1);
} }
}
break; break;
case 'F': case 'F':
fillfactor = atoi(optarg); fillfactor = atoi(optarg);
...@@ -1958,14 +1979,11 @@ main(int argc, char **argv) ...@@ -1958,14 +1979,11 @@ main(int argc, char **argv)
state[i].id = i; state[i].id = i;
for (j = 0; j < state[0].nvariables; j++) for (j = 0; j < state[0].nvariables; j++)
{ {
if (putVariable(&state[i], state[0].variables[j].name, state[0].variables[j].value) == false) if (!putVariable(&state[i], "startup", state[0].variables[j].name, state[0].variables[j].value))
{
fprintf(stderr, "Couldn't allocate memory for variable\n");
exit(1); exit(1);
} }
} }
} }
}
if (use_log) if (use_log)
{ {
...@@ -2039,13 +2057,10 @@ main(int argc, char **argv) ...@@ -2039,13 +2057,10 @@ main(int argc, char **argv)
snprintf(val, sizeof(val), "%d", scale); snprintf(val, sizeof(val), "%d", scale);
for (i = 0; i < nclients; i++) for (i = 0; i < nclients; i++)
{ {
if (putVariable(&state[i], "scale", val) == false) if (!putVariable(&state[i], "startup", "scale", val))
{
fprintf(stderr, "Couldn't allocate memory for variable\n");
exit(1); exit(1);
} }
} }
}
if (!is_no_vacuum) if (!is_no_vacuum)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment