]> granicus.if.org Git - postgresql/commitdiff
Fix length checking for Unicode identifiers containing escapes (U&"...").
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 13 Feb 2014 19:24:42 +0000 (14:24 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 13 Feb 2014 19:24:42 +0000 (14:24 -0500)
We used the length of the input string, not the de-escaped string, as
the trigger for NAMEDATALEN truncation.  AFAICS this would only result
in sometimes printing a phony truncation warning; but it's just luck
that there was no worse problem, since we were violating the API spec
for truncate_identifier().  Per bug #9204 from Joshua Yanovski.

This has been wrong since the Unicode-identifier support was added,
so back-patch to all supported branches.

src/backend/parser/scan.l

index e102e7c81e853a387c77b0a2ce42f46fedfa8427..146ae3db2d6657fc58ea77220d98fd4751ac2f43 100644 (file)
@@ -737,7 +737,8 @@ other                       .
 <xuiend>{xustop1} |
 <xuiend><<EOF>>        {
                                        /* no UESCAPE after the quote, throw back everything */
-                                       char               *ident;
+                                       char       *ident;
+                                       int                     identlen;
 
                                        yyless(0);
 
@@ -745,14 +746,16 @@ other                     .
                                        if (yyextra->literallen == 0)
                                                yyerror("zero-length delimited identifier");
                                        ident = litbuf_udeescape('\\', yyscanner);
-                                       if (yyextra->literallen >= NAMEDATALEN)
-                                               truncate_identifier(ident, yyextra->literallen, true);
+                                       identlen = strlen(ident);
+                                       if (identlen >= NAMEDATALEN)
+                                               truncate_identifier(ident, identlen, true);
                                        yylval->str = ident;
                                        return IDENT;
                                }
 <xuiend>{xustop2}      {
                                        /* found UESCAPE after the end quote */
-                                       char               *ident;
+                                       char       *ident;
+                                       int                     identlen;
 
                                        BEGIN(INITIAL);
                                        if (yyextra->literallen == 0)
@@ -764,8 +767,9 @@ other                       .
                                                yyerror("invalid Unicode escape character");
                                        }
                                        ident = litbuf_udeescape(yytext[yyleng - 2], yyscanner);
-                                       if (yyextra->literallen >= NAMEDATALEN)
-                                               truncate_identifier(ident, yyextra->literallen, true);
+                                       identlen = strlen(ident);
+                                       if (identlen >= NAMEDATALEN)
+                                               truncate_identifier(ident, identlen, true);
                                        yylval->str = ident;
                                        return IDENT;
                                }