mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
Fix up some oversights in psql's Unicode-escape support.
Original patch failed to include new exclusive states in a switch that needed to include them; and also was guilty of very fuzzy thinking about how to handle error cases. Per bug #5729 from Alan Choi.
This commit is contained in:
@ -120,7 +120,6 @@ static bool var_is_current_source(PsqlScanState state, const char *varname);
|
|||||||
static YY_BUFFER_STATE prepare_buffer(const char *txt, int len,
|
static YY_BUFFER_STATE prepare_buffer(const char *txt, int len,
|
||||||
char **txtcopy);
|
char **txtcopy);
|
||||||
static void emit(const char *txt, int len);
|
static void emit(const char *txt, int len);
|
||||||
static bool is_utf16_surrogate_first(uint32 c);
|
|
||||||
static void escape_variable(bool as_ident);
|
static void escape_variable(bool as_ident);
|
||||||
|
|
||||||
#define ECHO emit(yytext, yyleng)
|
#define ECHO emit(yytext, yyleng)
|
||||||
@ -163,7 +162,11 @@ static void escape_variable(bool as_ident);
|
|||||||
* <xdolq> $foo$ quoted strings
|
* <xdolq> $foo$ quoted strings
|
||||||
* <xui> quoted identifier with Unicode escapes
|
* <xui> quoted identifier with Unicode escapes
|
||||||
* <xus> quoted string with Unicode escapes
|
* <xus> quoted string with Unicode escapes
|
||||||
* <xeu> Unicode surrogate pair in extended quoted string
|
*
|
||||||
|
* Note: we intentionally don't mimic the backend's <xeu> state; we have
|
||||||
|
* no need to distinguish it from <xe> state, and no good way to get out
|
||||||
|
* of it in error cases. The backend just throws yyerror() in those
|
||||||
|
* cases, but that's not an option here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%x xb
|
%x xb
|
||||||
@ -175,7 +178,6 @@ static void escape_variable(bool as_ident);
|
|||||||
%x xdolq
|
%x xdolq
|
||||||
%x xui
|
%x xui
|
||||||
%x xus
|
%x xus
|
||||||
%x xeu
|
|
||||||
/* Additional exclusive states for psql only: lex backslash commands */
|
/* Additional exclusive states for psql only: lex backslash commands */
|
||||||
%x xslashcmd
|
%x xslashcmd
|
||||||
%x xslasharg
|
%x xslasharg
|
||||||
@ -529,19 +531,9 @@ other .
|
|||||||
ECHO;
|
ECHO;
|
||||||
}
|
}
|
||||||
<xe>{xeunicode} {
|
<xe>{xeunicode} {
|
||||||
uint32 c = strtoul(yytext+2, NULL, 16);
|
|
||||||
|
|
||||||
if (is_utf16_surrogate_first(c))
|
|
||||||
BEGIN(xeu);
|
|
||||||
ECHO;
|
ECHO;
|
||||||
}
|
}
|
||||||
<xeu>{xeunicode} {
|
<xe>{xeunicodefail} {
|
||||||
BEGIN(xe);
|
|
||||||
ECHO;
|
|
||||||
}
|
|
||||||
<xeu>. { ECHO; }
|
|
||||||
<xeu>\n { ECHO; }
|
|
||||||
<xe,xeu>{xeunicodefail} {
|
|
||||||
ECHO;
|
ECHO;
|
||||||
}
|
}
|
||||||
<xe>{xeescape} {
|
<xe>{xeescape} {
|
||||||
@ -1242,6 +1234,7 @@ psql_scan(PsqlScanState state,
|
|||||||
case LEXRES_EOL: /* end of input */
|
case LEXRES_EOL: /* end of input */
|
||||||
switch (state->start_state)
|
switch (state->start_state)
|
||||||
{
|
{
|
||||||
|
/* This switch must cover all non-slash-command states. */
|
||||||
case INITIAL:
|
case INITIAL:
|
||||||
if (state->paren_depth > 0)
|
if (state->paren_depth > 0)
|
||||||
{
|
{
|
||||||
@ -1276,11 +1269,11 @@ psql_scan(PsqlScanState state,
|
|||||||
result = PSCAN_INCOMPLETE;
|
result = PSCAN_INCOMPLETE;
|
||||||
*prompt = PROMPT_SINGLEQUOTE;
|
*prompt = PROMPT_SINGLEQUOTE;
|
||||||
break;
|
break;
|
||||||
case xq:
|
case xe:
|
||||||
result = PSCAN_INCOMPLETE;
|
result = PSCAN_INCOMPLETE;
|
||||||
*prompt = PROMPT_SINGLEQUOTE;
|
*prompt = PROMPT_SINGLEQUOTE;
|
||||||
break;
|
break;
|
||||||
case xe:
|
case xq:
|
||||||
result = PSCAN_INCOMPLETE;
|
result = PSCAN_INCOMPLETE;
|
||||||
*prompt = PROMPT_SINGLEQUOTE;
|
*prompt = PROMPT_SINGLEQUOTE;
|
||||||
break;
|
break;
|
||||||
@ -1288,6 +1281,14 @@ psql_scan(PsqlScanState state,
|
|||||||
result = PSCAN_INCOMPLETE;
|
result = PSCAN_INCOMPLETE;
|
||||||
*prompt = PROMPT_DOLLARQUOTE;
|
*prompt = PROMPT_DOLLARQUOTE;
|
||||||
break;
|
break;
|
||||||
|
case xui:
|
||||||
|
result = PSCAN_INCOMPLETE;
|
||||||
|
*prompt = PROMPT_DOUBLEQUOTE;
|
||||||
|
break;
|
||||||
|
case xus:
|
||||||
|
result = PSCAN_INCOMPLETE;
|
||||||
|
*prompt = PROMPT_SINGLEQUOTE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* can't get here */
|
/* can't get here */
|
||||||
fprintf(stderr, "invalid YY_START\n");
|
fprintf(stderr, "invalid YY_START\n");
|
||||||
@ -1814,12 +1815,6 @@ emit(const char *txt, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is_utf16_surrogate_first(uint32 c)
|
|
||||||
{
|
|
||||||
return (c >= 0xD800 && c <= 0xDBFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
escape_variable(bool as_ident)
|
escape_variable(bool as_ident)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user