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

Commitd4a63f8

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 parent5ca0077 commitd4a63f8

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
@@ -885,20 +885,33 @@ other.
885885
* to forbid operator names like '?-' that could not be
886886
* sequences of SQL operators.
887887
*/
888-
while (nchars >1 &&
889-
(yytext[nchars -1] =='+' ||
890-
yytext[nchars -1] =='-'))
888+
if (nchars >1 &&
889+
(yytext[nchars -1] =='+' ||
890+
yytext[nchars -1] =='-'))
891891
{
892892
intic;
893893

894894
for (ic = nchars -2; ic >=0; ic--)
895895
{
896-
if (strchr("~!@#^&|`?%", yytext[ic]))
896+
char c = yytext[ic];
897+
if (c =='~' || c =='!' || c =='@' ||
898+
c =='#' || c =='^' || c =='&' ||
899+
c =='|' || c =='`' || c =='?' ||
900+
c =='%')
897901
break;
898902
}
899-
if (ic >=0)
900-
break;/* found a char that makes it OK */
901-
nchars--;/* else remove the +/-, and check again */
903+
if (ic <0)
904+
{
905+
/*
906+
* didn't find a qualifying character, so remove
907+
* all trailing [+-]
908+
*/
909+
do {
910+
nchars--;
911+
}while (nchars >1 &&
912+
(yytext[nchars -1] =='+' ||
913+
yytext[nchars -1] =='-'));
914+
}
902915
}
903916

904917
SET_YYLLOC();

‎src/fe_utils/psqlscan.l

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -817,20 +817,33 @@ other.
817817
* to forbid operator names like '?-' that could not be
818818
* sequences of SQL operators.
819819
*/
820-
while (nchars >1 &&
821-
(yytext[nchars -1] =='+' ||
822-
yytext[nchars -1] =='-'))
820+
if (nchars >1 &&
821+
(yytext[nchars -1] =='+' ||
822+
yytext[nchars -1] =='-'))
823823
{
824824
intic;
825825

826826
for (ic = nchars -2; ic >=0; ic--)
827827
{
828-
if (strchr("~!@#^&|`?%", yytext[ic]))
828+
char c = yytext[ic];
829+
if (c =='~' || c =='!' || c =='@' ||
830+
c =='#' || c =='^' || c =='&' ||
831+
c =='|' || c =='`' || c =='?' ||
832+
c =='%')
829833
break;
830834
}
831-
if (ic >=0)
832-
break;/* found a char that makes it OK */
833-
nchars--;/* else remove the +/-, and check again */
835+
if (ic <0)
836+
{
837+
/*
838+
* didn't find a qualifying character, so remove
839+
* all trailing [+-]
840+
*/
841+
do {
842+
nchars--;
843+
}while (nchars >1 &&
844+
(yytext[nchars -1] =='+' ||
845+
yytext[nchars -1] =='-'));
846+
}
834847
}
835848

836849
if (nchars < yyleng)

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -690,20 +690,33 @@ cppline{space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
690690
* to forbid operator names like '?-' that could not be
691691
* sequences of SQL operators.
692692
*/
693-
while (nchars >1 &&
694-
(yytext[nchars-1] =='+' ||
695-
yytext[nchars-1] =='-'))
693+
if (nchars >1 &&
694+
(yytext[nchars -1] =='+' ||
695+
yytext[nchars -1] =='-'))
696696
{
697697
intic;
698698

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

709722
if (nchars < yyleng)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp