diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-22 10:39:20 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-22 10:39:20 +0100 |
commit | 76e0129a21661029dc6cdbea2412ab53efe33aa1 (patch) | |
tree | 8da626b89a277722edd445798679339234596956 /crates/ra_mbe | |
parent | bbc5c1d24e1a641b134f634516828301e8cfc320 (diff) | |
parent | ad1c3b5bd605942c85e4488b0483a0f50dc60942 (diff) |
Merge #1192
1192: Add mbe expand limit and poision macro set r=maklad a=edwin0cheng
As discussed in Zulip, this PR add a token expansion limit in `parse_macro` and a "poison" macro set in `CrateDefMap` to prevent stack over flow and limit a mbe macro size.
Note:
Right now it only handle a poison macro in a single crate, such that if other crate try to call that macro, the whole process will do again until it became poisoned in that crate.
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r-- | crates/ra_mbe/src/subtree_parser.rs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs index 528aa0f8a..f07107414 100644 --- a/crates/ra_mbe/src/subtree_parser.rs +++ b/crates/ra_mbe/src/subtree_parser.rs | |||
@@ -5,6 +5,7 @@ use ra_syntax::{SyntaxKind}; | |||
5 | 5 | ||
6 | struct OffsetTokenSink { | 6 | struct OffsetTokenSink { |
7 | token_pos: usize, | 7 | token_pos: usize, |
8 | error: bool, | ||
8 | } | 9 | } |
9 | 10 | ||
10 | impl TreeSink for OffsetTokenSink { | 11 | impl TreeSink for OffsetTokenSink { |
@@ -13,7 +14,9 @@ impl TreeSink for OffsetTokenSink { | |||
13 | } | 14 | } |
14 | fn start_node(&mut self, _kind: SyntaxKind) {} | 15 | fn start_node(&mut self, _kind: SyntaxKind) {} |
15 | fn finish_node(&mut self) {} | 16 | fn finish_node(&mut self) {} |
16 | fn error(&mut self, _error: ra_parser::ParseError) {} | 17 | fn error(&mut self, _error: ra_parser::ParseError) { |
18 | self.error = true; | ||
19 | } | ||
17 | } | 20 | } |
18 | 21 | ||
19 | pub(crate) struct Parser<'a> { | 22 | pub(crate) struct Parser<'a> { |
@@ -67,11 +70,15 @@ impl<'a> Parser<'a> { | |||
67 | F: FnOnce(&dyn TokenSource, &mut dyn TreeSink), | 70 | F: FnOnce(&dyn TokenSource, &mut dyn TreeSink), |
68 | { | 71 | { |
69 | let mut src = SubtreeTokenSource::new(&self.subtree.token_trees[*self.cur_pos..]); | 72 | let mut src = SubtreeTokenSource::new(&self.subtree.token_trees[*self.cur_pos..]); |
70 | let mut sink = OffsetTokenSink { token_pos: 0 }; | 73 | let mut sink = OffsetTokenSink { token_pos: 0, error: false }; |
71 | 74 | ||
72 | f(&src, &mut sink); | 75 | f(&src, &mut sink); |
73 | 76 | ||
74 | self.finish(sink.token_pos, &mut src) | 77 | let r = self.finish(sink.token_pos, &mut src); |
78 | if sink.error { | ||
79 | return None; | ||
80 | } | ||
81 | r | ||
75 | } | 82 | } |
76 | 83 | ||
77 | fn finish(self, parsed_token: usize, src: &mut SubtreeTokenSource) -> Option<tt::TokenTree> { | 84 | fn finish(self, parsed_token: usize, src: &mut SubtreeTokenSource) -> Option<tt::TokenTree> { |