diff options
author | oldmanmike <oldmanmike.dev@gmail.com> | 2016-11-03 13:28:33 -0500 |
---|---|---|
committer | oldmanmike <oldmanmike.dev@gmail.com> | 2016-11-03 13:28:33 -0500 |
commit | 59468b998549012e55007808cac3b90517291357 (patch) | |
tree | 5ae24bd44daf832cdf51443a8f2d1a0e96d61e1d | |
parent | 6d7d5dbd5da687cae29e525dcf2744eba85ab64d (diff) |
Add bounds checks to version parsing
-rwxr-xr-x | src/bin/bindgen.rs | 30 | ||||
-rwxr-xr-x | src/clang.rs | 6 | ||||
-rwxr-xr-x | src/lib.rs | 39 |
3 files changed, 34 insertions, 41 deletions
diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index 4c884448..3f3ff377 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -217,26 +217,18 @@ pub fn main() { let mut bind_args: Vec<_> = env::args().collect(); - match clang_version() { - None => { - error!("Could not retrieve Clang version...") - }, - Some(v) => { - if cfg!(feature = "llvm_stable") { - if (v.major,v.minor) != (3,8) { - error!("Got Clang {}.{}, expected 3.8", v.major, v.minor) - } else { - info!("Using: {}", v.full) - } - } else { - if (v.major, v.minor) != (3,9) { - error!("Got Clang {}.{}, expected 3.9", v.major, v.minor) - } else { - info!("Using: {}", v.full) - } - } + let version = clang_version(); + let expected_version = if cfg!(feature = "llvm_stable") { (3,8) } else { (3,9) }; + + info!("Clang Version: {}", version.full); + + match version.parsed { + None => warn!("Couldn't parse libclang version"), + Some(version) if version != expected_version => { + error!("Using clang {:?}, expected {:?}", version, expected_version); } - }; + _ => {} + } if let Some(clang) = clang_sys::support::Clang::find(None) { let has_clang_args = diff --git a/src/clang.rs b/src/clang.rs index 437c3f15..495e461e 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -1428,8 +1428,6 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { } /// Try to extract the clang version to a string -pub fn extract_clang_version() -> Option<String> { - let s: String = - unsafe { clang_getClangVersion().into() }; - if s.is_empty() { None } else { Some(s) } +pub fn extract_clang_version() -> String { + unsafe { clang_getClangVersion().into() } } @@ -452,30 +452,33 @@ fn parse(context: &mut BindgenContext) { /// Extracted Clang version data #[derive(Debug)] pub struct ClangVersion { - /// major semvar - pub major: u32, - /// minor semvar - pub minor: u32, + /// Major and minor semvar, if parsing was successful + pub parsed: Option<(u32,u32)>, /// full version string pub full: String, } /// Get the major and the minor semvar numbers of Clang's version -pub fn clang_version() -> Option<ClangVersion> { - let raw_v: String = match clang::extract_clang_version() { - None => return None, - Some(v) => v, - }; - let split_v: Vec<&str> = match raw_v.split_whitespace().nth(2) { - None => return None, - Some(v) => v.split_terminator('.').collect(), +pub fn clang_version() -> ClangVersion { + let raw_v: String = clang::extract_clang_version(); + let split_v: Option<Vec<&str>> = raw_v + .split_whitespace() + .nth(2) + .map(|v| v.split('.').collect()); + match split_v { + Some(v) => { + if v.len() >= 2 { + let maybe_major = v[0].parse::<u32>(); + let maybe_minor = v[1].parse::<u32>(); + match (maybe_major,maybe_minor) { + (Ok(major),Ok(minor)) => return ClangVersion { parsed: Some((major,minor)), full: raw_v.clone() }, + _ => {}, + } + } + }, + None => {}, }; - let maybe_major = split_v[0].parse::<u32>(); - let maybe_minor = split_v[1].parse::<u32>(); - match (maybe_major,maybe_minor) { - (Ok(major),Ok(minor)) => Some(ClangVersion { major: major, minor: minor, full: raw_v.clone() }), - _ => None, - } + ClangVersion { parsed: None, full: raw_v.clone() } } |