diff options
Diffstat (limited to 'src/fe_utils')
| -rw-r--r-- | src/fe_utils/psqlscan.l | 13 | ||||
| -rw-r--r-- | src/fe_utils/string_utils.c | 33 |
2 files changed, 31 insertions, 15 deletions
diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index 19b3e57aa4..27689d72da 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -699,8 +699,7 @@ other . yyleng - 1); if (cur_state->callbacks->get_variable) value = cur_state->callbacks->get_variable(varname, - false, - false, + PQUOTE_PLAIN, cur_state->cb_passthrough); else value = NULL; @@ -737,11 +736,13 @@ other . } :'{variable_char}+' { - psqlscan_escape_variable(cur_state, yytext, yyleng, false); + psqlscan_escape_variable(cur_state, yytext, yyleng, + PQUOTE_SQL_LITERAL); } :\"{variable_char}+\" { - psqlscan_escape_variable(cur_state, yytext, yyleng, true); + psqlscan_escape_variable(cur_state, yytext, yyleng, + PQUOTE_SQL_IDENT); } /* @@ -1415,7 +1416,7 @@ psqlscan_extract_substring(PsqlScanState state, const char *txt, int len) */ void psqlscan_escape_variable(PsqlScanState state, const char *txt, int len, - bool as_ident) + PsqlScanQuoteType quote) { char *varname; char *value; @@ -1423,7 +1424,7 @@ psqlscan_escape_variable(PsqlScanState state, const char *txt, int len, /* Variable lookup. */ varname = psqlscan_extract_substring(state, txt + 2, len - 3); if (state->callbacks->get_variable) - value = state->callbacks->get_variable(varname, true, as_ident, + value = state->callbacks->get_variable(varname, quote, state->cb_passthrough); else value = NULL; diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index d1a9ddc4c6..dc84d32a09 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -425,13 +425,30 @@ appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length, * arguments containing LF or CR characters. A future major release should * reject those characters in CREATE ROLE and CREATE DATABASE, because use * there eventually leads to errors here. + * + * appendShellString() simply prints an error and dies if LF or CR appears. + * appendShellStringNoError() omits those characters from the result, and + * returns false if there were any. */ void appendShellString(PQExpBuffer buf, const char *str) { + if (!appendShellStringNoError(buf, str)) + { + fprintf(stderr, + _("shell command argument contains a newline or carriage return: \"%s\"\n"), + str); + exit(EXIT_FAILURE); + } +} + +bool +appendShellStringNoError(PQExpBuffer buf, const char *str) +{ #ifdef WIN32 int backslash_run_length = 0; #endif + bool ok = true; const char *p; /* @@ -442,7 +459,7 @@ appendShellString(PQExpBuffer buf, const char *str) strspn(str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./:") == strlen(str)) { appendPQExpBufferStr(buf, str); - return; + return ok; } #ifndef WIN32 @@ -451,10 +468,8 @@ appendShellString(PQExpBuffer buf, const char *str) { if (*p == '\n' || *p == '\r') { - fprintf(stderr, - _("shell command argument contains a newline or carriage return: \"%s\"\n"), - str); - exit(EXIT_FAILURE); + ok = false; + continue; } if (*p == '\'') @@ -481,10 +496,8 @@ appendShellString(PQExpBuffer buf, const char *str) { if (*p == '\n' || *p == '\r') { - fprintf(stderr, - _("shell command argument contains a newline or carriage return: \"%s\"\n"), - str); - exit(EXIT_FAILURE); + ok = false; + continue; } /* Change N backslashes before a double quote to 2N+1 backslashes. */ @@ -524,6 +537,8 @@ appendShellString(PQExpBuffer buf, const char *str) } appendPQExpBufferStr(buf, "^\""); #endif /* WIN32 */ + + return ok; } |
