summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroldmanmike <oldmanmike.dev@gmail.com>2016-11-03 13:28:33 -0500
committeroldmanmike <oldmanmike.dev@gmail.com>2016-11-03 13:28:33 -0500
commit59468b998549012e55007808cac3b90517291357 (patch)
tree5ae24bd44daf832cdf51443a8f2d1a0e96d61e1d
parent6d7d5dbd5da687cae29e525dcf2744eba85ab64d (diff)
Add bounds checks to version parsing
-rwxr-xr-xsrc/bin/bindgen.rs30
-rwxr-xr-xsrc/clang.rs6
-rwxr-xr-xsrc/lib.rs39
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() }
}
diff --git a/src/lib.rs b/src/lib.rs
index c3e9203b..7b4d4e4b 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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() }
}