Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4854ead

Browse files
committed
Reduce an unnecessary O(N^3) loop in lexer.
The lexer's handling of operators contained an O(N^3) hazard whendealing with long strings of + or - characters; it seems hard toprevent this case from being O(N^2), but the additional N multiplierwas not needed.Backpatch all the way since this has been there since 7.x, and itpresents at least a mild hazard in that trying to do Bind, PREPARE orEXPLAIN on a hostile query could take excessive time (withouthonouring cancels or timeouts) even if the query was never executed.
1 parent90b0f30 commit4854ead

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

‎src/backend/parser/scan.l

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -881,20 +881,33 @@ other.
881881
* to forbid operator names like '?-' that could not be
882882
* sequences of SQL operators.
883883
*/
884-
while (nchars >1 &&
885-
(yytext[nchars -1] =='+' ||
886-
yytext[nchars -1] =='-'))
884+
if (nchars >1 &&
885+
(yytext[nchars -1] =='+' ||
886+
yytext[nchars -1] =='-'))
887887
{
888888
intic;
889889

890890
for (ic = nchars -2; ic >=0; ic--)
891891
{
892-
if (strchr("~!@#^&|`?%", yytext[ic]))
892+
char c = yytext[ic];
893+
if (c =='~' || c =='!' || c =='@' ||
894+
c =='#' || c =='^' || c =='&' ||
895+
c =='|' || c =='`' || c =='?' ||
896+
c =='%')
893897
break;
894898
}
895-
if (ic >=0)
896-
break;/* found a char that makes it OK */
897-
nchars--;/* else remove the +/-, and check again */
899+
if (ic <0)
900+
{
901+
/*
902+
* didn't find a qualifying character, so remove
903+
* all trailing [+-]
904+
*/
905+
do {
906+
nchars--;
907+
}while (nchars >1 &&
908+
(yytext[nchars -1] =='+' ||
909+
yytext[nchars -1] =='-'));
910+
}
898911
}
899912

900913
SET_YYLLOC();

‎src/fe_utils/psqlscan.l

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -798,20 +798,33 @@ other.
798798
* to forbid operator names like '?-' that could not be
799799
* sequences of SQL operators.
800800
*/
801-
while (nchars >1 &&
802-
(yytext[nchars -1] =='+' ||
803-
yytext[nchars -1] =='-'))
801+
if (nchars >1 &&
802+
(yytext[nchars -1] =='+' ||
803+
yytext[nchars -1] =='-'))
804804
{
805805
intic;
806806

807807
for (ic = nchars -2; ic >=0; ic--)
808808
{
809-
if (strchr("~!@#^&|`?%", yytext[ic]))
809+
char c = yytext[ic];
810+
if (c =='~' || c =='!' || c =='@' ||
811+
c =='#' || c =='^' || c =='&' ||
812+
c =='|' || c =='`' || c =='?' ||
813+
c =='%')
810814
break;
811815
}
812-
if (ic >=0)
813-
break;/* found a char that makes it OK */
814-
nchars--;/* else remove the +/-, and check again */
816+
if (ic <0)
817+
{
818+
/*
819+
* didn't find a qualifying character, so remove
820+
* all trailing [+-]
821+
*/
822+
do {
823+
nchars--;
824+
}while (nchars >1 &&
825+
(yytext[nchars -1] =='+' ||
826+
yytext[nchars -1] =='-'));
827+
}
815828
}
816829

817830
if (nchars < yyleng)

‎src/interfaces/ecpg/preproc/pgc.l

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -687,20 +687,33 @@ cppline{space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
687687
* to forbid operator names like '?-' that could not be
688688
* sequences of SQL operators.
689689
*/
690-
while (nchars >1 &&
691-
(yytext[nchars-1] =='+' ||
692-
yytext[nchars-1] =='-'))
690+
if (nchars >1 &&
691+
(yytext[nchars -1] =='+' ||
692+
yytext[nchars -1] =='-'))
693693
{
694694
intic;
695695

696-
for (ic = nchars-2; ic >=0; ic--)
696+
for (ic = nchars -2; ic >=0; ic--)
697697
{
698-
if (strchr("~!@#^&|`?%", yytext[ic]))
698+
char c = yytext[ic];
699+
if (c =='~' || c =='!' || c =='@' ||
700+
c =='#' || c =='^' || c =='&' ||
701+
c =='|' || c =='`' || c =='?' ||
702+
c =='%')
699703
break;
700704
}
701-
if (ic >=0)
702-
break;/* found a char that makes it OK */
703-
nchars--;/* else remove the +/-, and check again */
705+
if (ic <0)
706+
{
707+
/*
708+
* didn't find a qualifying character, so remove
709+
* all trailing [+-]
710+
*/
711+
do {
712+
nchars--;
713+
}while (nchars >1 &&
714+
(yytext[nchars -1] =='+' ||
715+
yytext[nchars -1] =='-'));
716+
}
704717
}
705718

706719
if (nchars < yyleng)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp