Skip to content

Commit b376906

Browse files
committed
In ecpg, automatically double single quotes in $$ strings because
internally $$ strings are converted to single-quote strings. In ecpg, output newlines in commands using standard C escapes, rather than using literal newlines, which is not portable.
1 parent 9190b4d commit b376906

File tree

2 files changed

+30
-29
lines changed

2 files changed

+30
-29
lines changed

src/interfaces/ecpg/preproc/output.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "extern.h"
44

5+
static void ouput_escaped_str(char *cmd);
6+
57
void
68
output_line_number(void)
79
{
@@ -10,21 +12,11 @@ output_line_number(void)
1012
}
1113

1214
void
13-
output_simple_statement(char *cmd)
15+
output_simple_statement(char *stmt)
1416
{
15-
int i,
16-
j = strlen(cmd);;
17-
18-
/* output this char by char as we have to filter '\"' */
19-
for (i = 0; i < j; i++)
20-
{
21-
if (cmd[i] != '"')
22-
fputc(cmd[i], yyout);
23-
else
24-
fputs("\\\"", yyout);
25-
}
17+
ouput_escaped_str(stmt);
2618
output_line_number();
27-
free(cmd);
19+
free(stmt);
2820
}
2921

3022
/*
@@ -106,20 +98,8 @@ hashline_number(void)
10698
void
10799
output_statement(char *stmt, int mode, char *con)
108100
{
109-
int i,
110-
j = strlen(stmt);
111-
112101
fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, \"", compat, force_indicator, con ? con : "NULL");
113-
114-
/* output this char by char as we have to filter '\"' */
115-
for (i = 0; i < j; i++)
116-
{
117-
if (stmt[i] != '"')
118-
fputc(stmt[i], yyout);
119-
else
120-
fputs("\\\"", yyout);
121-
}
122-
102+
ouput_escaped_str(stmt);
123103
fputs("\", ", yyout);
124104

125105
/* dump variables to C file */
@@ -135,3 +115,21 @@ output_statement(char *stmt, int mode, char *con)
135115
if (connection != NULL)
136116
free(connection);
137117
}
118+
119+
120+
static void
121+
ouput_escaped_str(char *str)
122+
{
123+
int i, len = strlen(str);
124+
125+
/* output this char by char as we have to filter " and \n */
126+
for (i = 0; i < len; i++)
127+
{
128+
if (str[i] == '"')
129+
fputs("\\\"", yyout);
130+
else if (str[i] == '\n')
131+
fputs("\\n\\\n", yyout);
132+
else
133+
fputc(str[i], yyout);
134+
}
135+
}

src/interfaces/ecpg/preproc/pgc.l

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.140 2006/02/02 03:51:41 momjian Exp $
15+
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.141 2006/02/04 02:32:38 momjian Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -152,7 +152,7 @@ dolq_start [A-Za-z\200-\377_]
152152
dolq_cont [A-Za-z\200-\377_0-9]
153153
dolqdelim \$({dolq_start}{dolq_cont}*)?\$
154154
dolqfailed \${dolq_start}{dolq_cont}*
155-
dolqinside [^$]+
155+
dolqinside [^$']+
156156

157157
/* Double quote
158158
* Allows embedded spaces and other special characters into identifiers.
@@ -476,7 +476,10 @@ cppline {space}*#(.*\\{space})*.*{newline}
476476
<xdolq>{dolqinside} { addlit(yytext, yyleng); }
477477
<xdolq>{dolqfailed} { addlit(yytext, yyleng); }
478478
<xdolq>. {
479-
/* This is only needed for $ inside the quoted text */
479+
/* $$ is implemented as a single-quoted string, so double it? */
480+
if (yytext[0] == '\'')
481+
addlitchar(yytext[0]);
482+
/* single quote or dollar sign */
480483
addlitchar(yytext[0]);
481484
}
482485
<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }

0 commit comments

Comments
 (0)