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

Commit2dbfbd6

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 parent6953daf commit2dbfbd6

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
@@ -800,20 +800,33 @@ other.
800800
* to forbid operator names like '?-' that could not be
801801
* sequences of SQL operators.
802802
*/
803-
while (nchars >1 &&
804-
(yytext[nchars -1] =='+' ||
805-
yytext[nchars -1] =='-'))
803+
if (nchars >1 &&
804+
(yytext[nchars -1] =='+' ||
805+
yytext[nchars -1] =='-'))
806806
{
807807
intic;
808808

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

819832
if (nchars < yyleng)

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

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

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

705718
if (nchars < yyleng)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp