Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
bcacaed4
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bcacaed4
编写于
1月 01, 2018
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Prevent stack overflows when parsing regexes.
上级
c37bc38f
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
88 addition
and
21 deletion
+88
-21
src/Features/Core/Portable/ValidateRegexString/AbstractValidateRegexStringDiagnosticAnalyzer.cs
...exString/AbstractValidateRegexStringDiagnosticAnalyzer.cs
+6
-1
src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/RegexPatternTokenClassifier.cs
...ation/SyntaxClassification/RegexPatternTokenClassifier.cs
+6
-1
src/Workspaces/CSharpTest/RegularExpressions/CSharpRegexParserTests.cs
...s/CSharpTest/RegularExpressions/CSharpRegexParserTests.cs
+38
-3
src/Workspaces/Core/Portable/RegularExpressions/RegexParser.cs
...orkspaces/Core/Portable/RegularExpressions/RegexParser.cs
+38
-16
未找到文件。
src/Features/Core/Portable/ValidateRegexString/AbstractValidateRegexStringDiagnosticAnalyzer.cs
浏览文件 @
bcacaed4
...
...
@@ -103,7 +103,12 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context)
return
;
}
var
tree
=
RegexParser
.
Parse
(
virtualChars
,
options
);
var
tree
=
RegexParser
.
TryParse
(
virtualChars
,
options
);
if
(
tree
==
null
)
{
return
;
}
foreach
(
var
diag
in
tree
.
Diagnostics
)
{
context
.
ReportDiagnostic
(
Diagnostic
.
Create
(
...
...
src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/RegexPatternTokenClassifier.cs
浏览文件 @
bcacaed4
...
...
@@ -51,7 +51,12 @@ public override void AddClassifications(Workspace workspace, SyntaxToken token,
return
;
}
var
tree
=
RegexParser
.
Parse
(
chars
,
options
);
var
tree
=
RegexParser
.
TryParse
(
chars
,
options
);
if
(
tree
==
null
)
{
return
;
}
var
visitor
=
new
Visitor
(
result
);
AddClassifications
(
tree
.
Root
,
visitor
,
result
);
}
...
...
src/Workspaces/CSharpTest/RegularExpressions/CSharpRegexParserTests.cs
浏览文件 @
bcacaed4
...
...
@@ -61,17 +61,30 @@ private void TryParseSubTrees(string stringText, RegexOptions options)
}
}
private
RegexTree
TryParseTree
(
string
stringText
,
RegexOptions
options
,
bool
conversionFailureOk
)
private
(
SyntaxToken
,
RegexTree
,
ImmutableArray
<
VirtualChar
>)
JustParseTree
(
string
stringText
,
RegexOptions
options
,
bool
conversionFailureOk
)
{
var
token
=
GetStringToken
(
stringText
);
var
allChars
=
_service
.
TryConvertToVirtualChars
(
token
);
if
(
allChars
.
IsDefault
)
{
Assert
.
True
(
conversionFailureOk
,
"Failed to convert text to token."
);
return
(
token
,
null
,
allChars
);
}
var
tree
=
RegexParser
.
TryParse
(
allChars
,
options
);
return
(
token
,
tree
,
allChars
);
}
private
RegexTree
TryParseTree
(
string
stringText
,
RegexOptions
options
,
bool
conversionFailureOk
)
{
var
(
token
,
tree
,
allChars
)
=
JustParseTree
(
stringText
,
options
,
conversionFailureOk
);
if
(
tree
==
null
)
{
Assert
.
True
(
conversionFailureOk
);
return
null
;
}
var
tree
=
RegexParser
.
Parse
(
allChars
,
options
);
Assert
.
NotNull
(
tree
);
CheckInvariants
(
tree
,
allChars
);
try
...
...
@@ -10341,5 +10354,27 @@ public void TestNegatedCharacterClass1()
}
#
endregion
[
Fact
]
public
void
TestDeepRecursion
()
{
var
(
token
,
tree
,
chars
)
=
JustParseTree
(
@"@""((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("""
,
RegexOptions
.
None
,
conversionFailureOk
:
false
);
Assert
.
False
(
token
.
IsMissing
);
Assert
.
False
(
chars
.
IsDefaultOrEmpty
);
Assert
.
Null
(
tree
);
}
}
}
src/Workspaces/Core/Portable/RegularExpressions/RegexParser.cs
浏览文件 @
bcacaed4
...
...
@@ -21,6 +21,7 @@ internal struct RegexParser
private
RegexToken
_currentToken
;
private
readonly
List
<
string
>
_captureNames
;
private
readonly
List
<
int
>
_captureNumbers
;
private
int
_recursionDepth
;
private
RegexParser
(
ImmutableArray
<
VirtualChar
>
text
,
RegexOptions
options
,
...
...
@@ -42,25 +43,32 @@ private RegexToken ScanNextToken(bool allowTrivia)
return
_currentToken
;
}
public
static
RegexTree
Parse
(
ImmutableArray
<
VirtualChar
>
text
,
RegexOptions
options
)
public
static
RegexTree
Try
Parse
(
ImmutableArray
<
VirtualChar
>
text
,
RegexOptions
options
)
{
// Parse the tree once, to figure out the capture groups. These are needed
// to then parse the tree again, as the captures will affect how we interpret
// certain things (i.e. escape references) and what errors will be reported.
//
// This is necessary as .net regexes allow references to *future* captures.
// As such, we don't know when we're seeing a reference if it's to something
// that exists or not.
var
tree1
=
new
RegexParser
(
text
,
options
,
null
,
null
).
ParseTree
();
try
{
// Parse the tree once, to figure out the capture groups. These are needed
// to then parse the tree again, as the captures will affect how we interpret
// certain things (i.e. escape references) and what errors will be reported.
//
// This is necessary as .net regexes allow references to *future* captures.
// As such, we don't know when we're seeing a reference if it's to something
// that exists or not.
var
tree1
=
new
RegexParser
(
text
,
options
,
null
,
null
).
ParseTree
();
var
captureNames
=
new
List
<
string
>();
var
captureNumbers
=
new
List
<
int
>
{
0
};
var
autoNumber
=
1
;
CollectCaptures
(
tree1
.
Root
,
captureNames
,
captureNumbers
,
ref
autoNumber
);
AssignNumbersToCaptureNames
(
captureNames
,
captureNumbers
,
autoNumber
);
var
captureNames
=
new
List
<
string
>();
var
captureNumbers
=
new
List
<
int
>
{
0
};
var
autoNumber
=
1
;
CollectCaptures
(
tree1
.
Root
,
captureNames
,
captureNumbers
,
ref
autoNumber
);
AssignNumbersToCaptureNames
(
captureNames
,
captureNumbers
,
autoNumber
);
var
tree2
=
new
RegexParser
(
text
,
options
,
captureNames
,
captureNumbers
).
ParseTree
();
return
tree2
;
var
tree2
=
new
RegexParser
(
text
,
options
,
captureNames
,
captureNumbers
).
ParseTree
();
return
tree2
;
}
catch
(
Exception
e
)
when
(
StackGuard
.
IsInsufficientExecutionStackException
(
e
))
{
return
null
;
}
}
private
static
void
AssignNumbersToCaptureNames
(
List
<
string
>
captureNames
,
List
<
int
>
captureNumbers
,
int
autoNumber
)
...
...
@@ -192,6 +200,20 @@ private void CollectDiagnostics(RegexToken token)
}
private
RegexExpressionNode
ParseExpression
(
bool
consumeCloseParen
)
{
try
{
_recursionDepth
++;
StackGuard
.
EnsureSufficientExecutionStack
(
_recursionDepth
);
return
ParseExpressionWorker
(
consumeCloseParen
);
}
finally
{
_recursionDepth
--;
}
}
private
RegexExpressionNode
ParseExpressionWorker
(
bool
consumeCloseParen
)
{
RegexExpressionNode
current
=
ParseSequence
(
consumeCloseParen
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录