mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	Reduce an unnecessary O(N^3) loop in lexer.
The lexer's handling of operators contained an O(N^3) hazard when dealing with long strings of + or - characters; it seems hard to prevent this case from being O(N^2), but the additional N multiplier was not needed. Backpatch all the way since this has been there since 7.x, and it presents at least a mild hazard in that trying to do Bind, PREPARE or EXPLAIN on a hostile query could take excessive time (without honouring cancels or timeouts) even if the query was never executed.
This commit is contained in:
		| @@ -885,20 +885,33 @@ other			. | ||||
| 					 * to forbid operator names like '?-' that could not be | ||||
| 					 * sequences of SQL operators. | ||||
| 					 */ | ||||
| 					while (nchars > 1 && | ||||
| 						   (yytext[nchars - 1] == '+' || | ||||
| 							yytext[nchars - 1] == '-')) | ||||
| 					if (nchars > 1 && | ||||
| 						(yytext[nchars - 1] == '+' || | ||||
| 						 yytext[nchars - 1] == '-')) | ||||
| 					{ | ||||
| 						int			ic; | ||||
|  | ||||
| 						for (ic = nchars - 2; ic >= 0; ic--) | ||||
| 						{ | ||||
| 							if (strchr("~!@#^&|`?%", yytext[ic])) | ||||
| 							char c = yytext[ic]; | ||||
| 							if (c == '~' || c == '!' || c == '@' || | ||||
| 								c == '#' || c == '^' || c == '&' || | ||||
| 								c == '|' || c == '`' || c == '?' || | ||||
| 								c == '%') | ||||
| 								break; | ||||
| 						} | ||||
| 						if (ic >= 0) | ||||
| 							break; /* found a char that makes it OK */ | ||||
| 						nchars--; /* else remove the +/-, and check again */ | ||||
| 						if (ic < 0) | ||||
| 						{ | ||||
| 							/* | ||||
| 							 * didn't find a qualifying character, so remove | ||||
| 							 * all trailing [+-] | ||||
| 							 */ | ||||
| 							do { | ||||
| 								nchars--; | ||||
| 							} while (nchars > 1 && | ||||
| 								 (yytext[nchars - 1] == '+' || | ||||
| 								  yytext[nchars - 1] == '-')); | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					SET_YYLLOC(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user