1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-03 15:22:11 +03:00

Check number of parameters in RAISE statement at compile time.

The number of % parameter markers in RAISE statement should match the number
of parameters given. We used to check that at execution time, but we have
all the information needed at compile time, so let's check it at compile
time instead. It's generally better to find mistakes earlier.

Marko Tiikkaja, reviewed by Fabien Coelho
This commit is contained in:
Heikki Linnakangas
2014-09-02 15:53:06 +03:00
parent f8f4227976
commit c1008f0037
5 changed files with 68 additions and 17 deletions

View File

@@ -2939,10 +2939,9 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
continue;
}
/* should have been checked at compile time */
if (current_param == NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too few parameters specified for RAISE")));
elog(ERROR, "unexpected RAISE parameter list length");
paramvalue = exec_eval_expr(estate,
(PLpgSQL_expr *) lfirst(current_param),
@@ -2963,14 +2962,9 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
appendStringInfoChar(&ds, cp[0]);
}
/*
* If more parameters were specified than were required to process the
* format string, throw an error
*/
/* should have been checked at compile time */
if (current_param != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too many parameters specified for RAISE")));
elog(ERROR, "unexpected RAISE parameter list length");
err_message = ds.data;
/* No pfree(ds.data), the pfree(err_message) does it */

View File

@@ -106,6 +106,7 @@ static void check_labels(const char *start_label,
static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor,
int until, const char *expected);
static List *read_raise_options(void);
static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
%}
@@ -1849,6 +1850,8 @@ stmt_raise : K_RAISE
new->options = read_raise_options();
}
check_raise_parameters(new);
$$ = (PLpgSQL_stmt *)new;
}
;
@@ -3767,6 +3770,41 @@ read_raise_options(void)
return result;
}
/*
* Check that the number of parameter placeholders in the message matches the
* number of parameters passed to it, if a message was given.
*/
static void
check_raise_parameters(PLpgSQL_stmt_raise *stmt)
{
char *cp;
int expected_nparams = 0;
if (stmt->message == NULL)
return;
for (cp = stmt->message; *cp; cp++)
{
if (cp[0] == '%')
{
/* ignore literal % characters */
if (cp[1] == '%')
cp++;
else
expected_nparams++;
}
}
if (expected_nparams < list_length(stmt->params))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too many parameters specified for RAISE")));
if (expected_nparams > list_length(stmt->params))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too few parameters specified for RAISE")));
}
/*
* Fix up CASE statement
*/