Skip to content

Commit faa1a7c

Browse files
authored
Merge pull request #375 from dtolnay/include
Check for disallowed include strings in Cargo-based workflow
2 parents d510763 + 75c2385 commit faa1a7c

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

gen/build/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,10 @@ fn make_include_dir(prj: &Project) -> Result<PathBuf> {
271271
}
272272

273273
fn generate_bridge(prj: &Project, build: &mut Build, rust_source_file: &Path) -> Result<()> {
274-
let opt = Opt::default();
274+
let opt = Opt {
275+
allow_dot_includes: false,
276+
..Opt::default()
277+
};
275278
let generated = gen::generate_from_path(rust_source_file, &opt);
276279
let ref rel_path = paths::local_relative_path(rust_source_file);
277280

gen/cmd/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ fn try_main() -> Result<()> {
6666
cxx_impl_annotations: opt.cxx_impl_annotations,
6767
gen_header,
6868
gen_implementation,
69+
..Default::default()
6970
};
7071

7172
let generated_code = if let Some(input) = opt.input {

gen/src/check.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::gen::Opt;
2+
use crate::syntax::report::Errors;
3+
use crate::syntax::{error, Api};
4+
use quote::{quote, quote_spanned};
5+
use std::path::{Component, Path};
6+
7+
pub(super) use crate::syntax::check::typecheck;
8+
9+
pub(super) fn precheck(cx: &mut Errors, apis: &[Api], opt: &Opt) {
10+
if !opt.allow_dot_includes {
11+
check_dot_includes(cx, apis);
12+
}
13+
}
14+
15+
fn check_dot_includes(cx: &mut Errors, apis: &[Api]) {
16+
for api in apis {
17+
if let Api::Include(include) = api {
18+
let first_component = Path::new(&include.path).components().next();
19+
if let Some(Component::CurDir) | Some(Component::ParentDir) = first_component {
20+
let begin = quote_spanned!(include.begin_span=> .);
21+
let end = quote_spanned!(include.end_span=> .);
22+
let span = quote!(#begin #end);
23+
cx.error(span, error::DOT_INCLUDE.msg);
24+
}
25+
}
26+
}
27+
}

gen/src/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Functionality that is shared between the cxx_build::bridge entry point and
22
// the cxxbridge CLI command.
33

4+
mod check;
45
pub(super) mod error;
56
mod file;
67
pub(super) mod fs;
@@ -13,7 +14,7 @@ use self::error::{format_err, Result};
1314
use self::file::File;
1415
use self::include::Include;
1516
use crate::syntax::report::Errors;
16-
use crate::syntax::{self, check, Types};
17+
use crate::syntax::{self, Types};
1718
use std::path::Path;
1819

1920
/// Options for C++ code generation.
@@ -45,6 +46,7 @@ pub struct Opt {
4546

4647
pub(super) gen_header: bool,
4748
pub(super) gen_implementation: bool,
49+
pub(super) allow_dot_includes: bool,
4850
}
4951

5052
/// Results of code generation.
@@ -63,6 +65,7 @@ impl Default for Opt {
6365
cxx_impl_annotations: None,
6466
gen_header: true,
6567
gen_implementation: true,
68+
allow_dot_includes: true,
6669
}
6770
}
6871
}
@@ -112,6 +115,7 @@ pub(super) fn generate(syntax: File, opt: &Opt) -> Result<GeneratedCode> {
112115
let trusted = bridge.unsafety.is_some();
113116
let ref apis = syntax::parse_items(errors, bridge.content, trusted);
114117
let ref types = Types::collect(errors, apis);
118+
check::precheck(errors, apis, opt);
115119
errors.propagate()?;
116120
check::typecheck(errors, namespace, apis, types);
117121
errors.propagate()?;

syntax/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub static ERRORS: &[Error] = &[
1919
CXX_STRING_BY_VALUE,
2020
CXX_TYPE_BY_VALUE,
2121
DISCRIMINANT_OVERFLOW,
22+
DOT_INCLUDE,
2223
DOUBLE_UNDERSCORE,
2324
RUST_TYPE_BY_VALUE,
2425
USE_NOT_ALLOWED,
@@ -54,6 +55,12 @@ pub static DISCRIMINANT_OVERFLOW: Error = Error {
5455
note: Some("note: explicitly set `= 0` if that is desired outcome"),
5556
};
5657

58+
pub static DOT_INCLUDE: Error = Error {
59+
msg: "#include relative to `.` or `..` is not supported in Cargo builds",
60+
label: Some("#include relative to `.` or `..` is not supported in Cargo builds"),
61+
note: Some("note: use a path starting with the crate name"),
62+
};
63+
5764
pub static DOUBLE_UNDERSCORE: Error = Error {
5865
msg: "identifiers containing double underscore are reserved in C++",
5966
label: Some("reserved identifier"),

0 commit comments

Comments
 (0)