about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2014-10-01 11:38:54 +0200
committerFlorian Hahn <flo@fhahn.com>2014-10-01 11:46:04 +0200
commit49e976d771d9a3282bb0f58f28e5e92d10c2e4c6 (patch)
tree26080db909dc531efc47abbcbc0efe10ec7aef12 /src/libsyntax
parent60e7317345f246a8169bbfe721473f693d54cade (diff)
downloadrust-49e976d771d9a3282bb0f58f28e5e92d10c2e4c6.tar.gz
rust-49e976d771d9a3282bb0f58f28e5e92d10c2e4c6.zip
Limit recursion depth for macro expansions, closes #17628
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs10
-rw-r--r--src/libsyntax/ext/expand.rs2
2 files changed, 12 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 212cd33e16e..a137f6e78b8 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -463,6 +463,7 @@ pub struct ExtCtxt<'a> {
     pub exported_macros: Vec<P<ast::Item>>,
 
     pub syntax_env: SyntaxEnv,
+    pub recursion_count: uint,
 }
 
 impl<'a> ExtCtxt<'a> {
@@ -478,6 +479,7 @@ impl<'a> ExtCtxt<'a> {
             trace_mac: false,
             exported_macros: Vec::new(),
             syntax_env: env,
+            recursion_count: 0,
         }
     }
 
@@ -552,6 +554,13 @@ impl<'a> ExtCtxt<'a> {
         return v;
     }
     pub fn bt_push(&mut self, ei: ExpnInfo) {
+        self.recursion_count += 1;
+        if self.recursion_count > self.ecfg.recursion_limit {
+            self.span_fatal(ei.call_site,
+                            format!("Recursion limit reached while expanding the macro `{}`",
+                                    ei.callee.name).as_slice());
+        }
+
         let mut call_site = ei.call_site;
         call_site.expn_id = self.backtrace;
         self.backtrace = self.codemap().record_expansion(ExpnInfo {
@@ -563,6 +572,7 @@ impl<'a> ExtCtxt<'a> {
         match self.backtrace {
             NO_EXPANSION => self.bug("tried to pop without a push"),
             expn_id => {
+                self.recursion_count -= 1;
                 self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| {
                     expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id)
                 });
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index fa3ccc8cf32..efe4b76354f 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1069,6 +1069,7 @@ pub struct ExpansionConfig {
     pub crate_name: String,
     pub deriving_hash_type_parameter: bool,
     pub enable_quotes: bool,
+    pub recursion_limit: uint,
 }
 
 impl ExpansionConfig {
@@ -1077,6 +1078,7 @@ impl ExpansionConfig {
             crate_name: crate_name,
             deriving_hash_type_parameter: false,
             enable_quotes: false,
+            recursion_limit: 64,
         }
     }
 }