From bd4b28868ac20fb348c95bc9c0f677abf82a80ef Mon Sep 17 00:00:00 2001 From: dalance Date: Thu, 12 Dec 2019 10:26:03 +0900 Subject: [PATCH] Allow recursive define until limit --- CHANGELOG.md | 2 ++ sv-parser-error/src/lib.rs | 4 ++-- sv-parser-pp/src/preprocess.rs | 23 ++++++++++++----------- sv-parser/src/lib.rs | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b629693..5514d59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.4.7...Unreleased) - ReleaseDate +* [Fixed] allow recursive define until limit + ## [v0.4.7](https://github.com/dalance/sv-parser/compare/v0.4.6...v0.4.7) - 2019-12-10 * [Added] recursive define detection diff --git a/sv-parser-error/src/lib.rs b/sv-parser-error/src/lib.rs index a686640..22f3d65 100644 --- a/sv-parser-error/src/lib.rs +++ b/sv-parser-error/src/lib.rs @@ -24,8 +24,8 @@ pub enum ErrorKind { DefineNotFound(String), #[fail(display = "Define must have argument")] DefineNoArgs, - #[fail(display = "Recursive define is detected: {}", _0)] - DefineRecursive(String), + #[fail(display = "Exceed recursive limit")] + ExceedRecursiveLimit, } // ----------------------------------------------------------------------------- diff --git a/sv-parser-pp/src/preprocess.rs b/sv-parser-pp/src/preprocess.rs index 25b3909..fac6543 100644 --- a/sv-parser-pp/src/preprocess.rs +++ b/sv-parser-pp/src/preprocess.rs @@ -13,6 +13,8 @@ use sv_parser_syntaxtree::{ IncludeCompilerDirective, Locate, NodeEvent, RefNode, SourceDescription, TextMacroUsage, }; +const RECURSIVE_LIMIT: usize = 128; + #[derive(Debug)] pub struct PreprocessedText { text: String, @@ -124,7 +126,7 @@ pub fn preprocess, U: AsRef>( let mut s = String::new(); reader.read_to_string(&mut s)?; - preprocess_str(&s, path, pre_defines, include_paths, vec![]) + preprocess_str(&s, path, pre_defines, include_paths, 0) } pub fn preprocess_str, U: AsRef>( @@ -132,7 +134,7 @@ pub fn preprocess_str, U: AsRef>( path: T, pre_defines: &Defines, include_paths: &[U], - resolved_defines: Vec, + resolve_depth: usize, ) -> Result<(PreprocessedText, Defines), Error> { let mut skip = false; let mut skip_nodes = vec![]; @@ -335,7 +337,7 @@ pub fn preprocess_str, U: AsRef>( path.as_ref(), &defines, include_paths, - resolved_defines.clone(), + resolve_depth + 1, )? { let p = p.trim().trim_matches('"'); PathBuf::from(p) @@ -367,7 +369,7 @@ pub fn preprocess_str, U: AsRef>( path.as_ref(), &defines, include_paths, - resolved_defines.clone(), + resolve_depth + 1, )? { ret.push(&text, origin); defines = new_defines; @@ -444,15 +446,14 @@ fn resolve_text_macro_usage, U: AsRef>( path: T, defines: &Defines, include_paths: &[U], - mut resolved_defines: Vec, + resolve_depth: usize, ) -> Result, Defines)>, Error> { let (_, ref name, ref args) = x.nodes; let id = identifier((&name.nodes.0).into(), &s).unwrap(); - if resolved_defines.contains(&id) { - return Err(ErrorKind::DefineRecursive(id).into()); + if resolve_depth > RECURSIVE_LIMIT { + return Err(ErrorKind::ExceedRecursiveLimit.into()); } - resolved_defines.push(id.clone()); let mut actual_args = Vec::new(); let no_args = args.is_none(); @@ -526,7 +527,7 @@ fn resolve_text_macro_usage, U: AsRef>( path.as_ref(), &defines, include_paths, - resolved_defines, + resolve_depth, )?; Ok(Some(( String::from(replaced.text()), @@ -709,7 +710,7 @@ endmodule let ret = preprocess(get_testcase("test7.sv"), &HashMap::new(), &[] as &[String]); assert_eq!( format!("{:?}", ret), - "Err(Error { inner: \n\nRecursive define is detected: a })" + "Err(Error { inner: \n\nExceed recursive limit })" ); } @@ -718,7 +719,7 @@ endmodule let ret = preprocess(get_testcase("test8.sv"), &HashMap::new(), &[] as &[String]); assert_eq!( format!("{:?}", ret), - "Err(Error { inner: \n\nRecursive define is detected: b })" + "Err(Error { inner: \n\nExceed recursive limit })" ); } } diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index 9d5a908..eec62c5 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -130,7 +130,7 @@ pub fn parse_sv_str, U: AsRef>( pre_defines: &HashMap>, include_paths: &[U], ) -> Result<(SyntaxTree, Defines), Error> { - let (text, defines) = preprocess_str(s, path, pre_defines, include_paths, vec![])?; + let (text, defines) = preprocess_str(s, path, pre_defines, include_paths, 0)?; let span = Span::new_extra(text.text(), SpanInfo::default()); let result = all_consuming(sv_parser)(span); match result { @@ -203,7 +203,7 @@ pub fn parse_lib_str, U: AsRef>( pre_defines: &HashMap>, include_paths: &[U], ) -> Result<(SyntaxTree, Defines), Error> { - let (text, defines) = preprocess_str(s, path, pre_defines, include_paths, vec![])?; + let (text, defines) = preprocess_str(s, path, pre_defines, include_paths, 0)?; let span = Span::new_extra(text.text(), SpanInfo::default()); let result = all_consuming(lib_parser)(span); match result {