summaryrefslogtreecommitdiff
path: root/src/fe_utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/fe_utils')
-rw-r--r--src/fe_utils/psqlscan.l13
-rw-r--r--src/fe_utils/string_utils.c33
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;
}