Fix length checking for Unicode identifiers containing escapes (U&"...").
authorTom Lane <[email protected]>
Thu, 13 Feb 2014 19:24:58 +0000 (14:24 -0500)
committerTom Lane <[email protected]>
Thu, 13 Feb 2014 19:24:58 +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 6e18a41db1e6c42c5501c8af473d4860eae68e37..f8c18689f8406139c4aab358171b7ff724a0a2aa 100644 (file)
@@ -620,28 +620,32 @@ other         .
                    return IDENT;
                }
 <xui>{xuistop1}    {
-                   char           *ident;
+                   char       *ident;
+                   int         identlen;
 
                    BEGIN(INITIAL);
                    if (literallen == 0)
                        yyerror("zero-length delimited identifier");
                    ident = litbuf_udeescape('\\');
-                   if (literallen >= NAMEDATALEN)
-                       truncate_identifier(ident, literallen, true);
+                   identlen = strlen(ident);
+                   if (identlen >= NAMEDATALEN)
+                       truncate_identifier(ident, identlen, true);
                    yylval.str = ident;
                    /* throw back all but the quote */
                    yyless(1);
                    return IDENT;
                }
 <xui>{xuistop2}    {
-                   char           *ident;
+                   char       *ident;
+                   int         identlen;
 
                    BEGIN(INITIAL);
                    if (literallen == 0)
                        yyerror("zero-length delimited identifier");
                    ident = litbuf_udeescape(yytext[yyleng - 2]);
-                   if (literallen >= NAMEDATALEN)
-                       truncate_identifier(ident, literallen, true);
+                   identlen = strlen(ident);
+                   if (identlen >= NAMEDATALEN)
+                       truncate_identifier(ident, identlen, true);
                    yylval.str = ident;
                    return IDENT;
                }