mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 21:06:50 -05:00
Simplify or optimize regexes with polynomial time worst cases (#44197)
* Simplify or optimize regexes with polynomial time worst cases * PR feedback & cleanup Co-authored-by: David Michon <dmichon-msft@users.noreply.github.com> * Use builtin scanner function for checking whitespace in fallback method (its faster) Co-authored-by: David Michon <dmichon-msft@users.noreply.github.com>
This commit is contained in:
@@ -806,7 +806,8 @@ namespace ts {
|
||||
|
||||
function tryClassifyTripleSlashComment(start: number, width: number): boolean {
|
||||
const tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/im;
|
||||
const attributeRegex = /(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img;
|
||||
// Require a leading whitespace character (the parser already does) to prevent terrible backtracking performance
|
||||
const attributeRegex = /(\s)(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img;
|
||||
|
||||
const text = sourceFile.text.substr(start, width);
|
||||
const match = tripleSlashXMLCommentRegEx.exec(text);
|
||||
@@ -842,30 +843,30 @@ namespace ts {
|
||||
break;
|
||||
}
|
||||
|
||||
const newAttrPos = pos + attrMatch.index;
|
||||
const newAttrPos = pos + attrMatch.index + attrMatch[1].length; // whitespace
|
||||
if (newAttrPos > attrPos) {
|
||||
pushCommentRange(attrPos, newAttrPos - attrPos);
|
||||
attrPos = newAttrPos;
|
||||
}
|
||||
|
||||
pushClassification(attrPos, attrMatch[1].length, ClassificationType.jsxAttribute); // attribute name
|
||||
attrPos += attrMatch[1].length;
|
||||
pushClassification(attrPos, attrMatch[2].length, ClassificationType.jsxAttribute); // attribute name
|
||||
attrPos += attrMatch[2].length;
|
||||
|
||||
if (attrMatch[2].length) {
|
||||
pushCommentRange(attrPos, attrMatch[2].length); // whitespace
|
||||
attrPos += attrMatch[2].length;
|
||||
if (attrMatch[3].length) {
|
||||
pushCommentRange(attrPos, attrMatch[3].length); // whitespace
|
||||
attrPos += attrMatch[3].length;
|
||||
}
|
||||
|
||||
pushClassification(attrPos, attrMatch[3].length, ClassificationType.operator); // =
|
||||
attrPos += attrMatch[3].length;
|
||||
pushClassification(attrPos, attrMatch[4].length, ClassificationType.operator); // =
|
||||
attrPos += attrMatch[4].length;
|
||||
|
||||
if (attrMatch[4].length) {
|
||||
pushCommentRange(attrPos, attrMatch[4].length); // whitespace
|
||||
attrPos += attrMatch[4].length;
|
||||
if (attrMatch[5].length) {
|
||||
pushCommentRange(attrPos, attrMatch[5].length); // whitespace
|
||||
attrPos += attrMatch[5].length;
|
||||
}
|
||||
|
||||
pushClassification(attrPos, attrMatch[5].length, ClassificationType.jsxAttributeStringLiteralValue); // attribute value
|
||||
attrPos += attrMatch[5].length;
|
||||
pushClassification(attrPos, attrMatch[6].length, ClassificationType.jsxAttributeStringLiteralValue); // attribute value
|
||||
attrPos += attrMatch[6].length;
|
||||
}
|
||||
|
||||
pos += match[4].length;
|
||||
|
||||
@@ -94,8 +94,15 @@ namespace ts.OutliningElementsCollector {
|
||||
}
|
||||
}
|
||||
|
||||
const regionDelimiterRegExp = /^\s*\/\/\s*#(end)?region(?:\s+(.*))?(?:\r)?$/;
|
||||
const regionDelimiterRegExp = /^#(end)?region(?:\s+(.*))?(?:\r)?$/;
|
||||
function isRegionDelimiter(lineText: string) {
|
||||
// We trim the leading whitespace and // without the regex since the
|
||||
// multiple potential whitespace matches can make for some gnarly backtracking behavior
|
||||
lineText = trimStringStart(lineText);
|
||||
if (!startsWith(lineText, "\/\/")) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
}
|
||||
lineText = trimString(lineText.slice(2));
|
||||
return regionDelimiterRegExp.exec(lineText);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user