From: Tom Lane Date: Wed, 16 Oct 2024 16:24:57 +0000 (-0400) Subject: ecpg: fix some minor mishandling of bad input in preprocessor. X-Git-Tag: REL_18_BETA1~1700 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=9b4bf5169064044ff082c61bf0783c4a65c08734;p=postgresql.git ecpg: fix some minor mishandling of bad input in preprocessor. Avoid null-pointer crash when considering a cursor declaration that's outside any C function (a case which is useless anyway). Ensure a cursor for a prepared statement is marked as initially not open. At worst, if we chanced to get not-already-zeroed memory from malloc(), this oversight would result in failing to issue a "cursor "foo" has been declared but not opened" warning that would have been appropriate. Avoid running off the end of the buffer when there are mismatched square brackets following a variable name. This could lead to SIGSEGV after reaching the end of memory. Given the lack of field complaints, none of these seem to be worth back-patching, but let's clean them up in HEAD. Per valgrind testing by Alexander Lakhin. Discussion: https://postgr.es/m/5f5bcecd-d7ec-b8c0-6c92-d1a7c6e0f639@gmail.com --- diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index d3df8eabbb7..a415780faff 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -432,7 +432,8 @@ adjust_outofscope_cursor_vars(struct cursor *cur) /* This tests whether the cursor was declared and opened in the same function. */ #define SAMEFUNC(cur) \ ((cur->function == NULL) || \ - (cur->function != NULL && strcmp(cur->function, current_function) == 0)) + (cur->function != NULL && current_function != NULL && \ + strcmp(cur->function, current_function) == 0)) static struct cursor * add_additional_variables(const char *name, bool insert) diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 0a77559e83b..e466668ea24 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -433,6 +433,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_ this->name = mm_strdup(@2); this->function = (current_function ? mm_strdup(current_function) : NULL); this->connection = connection ? mm_strdup(connection) : NULL; + this->opened = false; this->command = mm_strdup(cat_str(6, "declare", cursor_marker, @3, "cursor", @5, "for $1")); this->argsresult = NULL; this->argsresult_oos = NULL; diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index 6b87d5ff3d9..a4294b8f0ff 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -216,6 +216,9 @@ find_variable(const char *name) case ']': count--; break; + case '\0': + mmfatal(PARSE_ERROR, "unmatched brace in variable \"%s\"", name); + break; default: break; }