Skip to content

Commit 275005c

Browse files
committed
Add large_include_file lint
1 parent a9d31e7 commit 275005c

File tree

11 files changed

+120
-1
lines changed

11 files changed

+120
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3478,6 +3478,7 @@ Released 2018-09-13
34783478
[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
34793479
[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups
34803480
[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
3481+
[`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file
34813482
[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
34823483
[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value
34833484
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::macros::root_macro_call_first_node;
3+
use rustc_ast::LitKind;
4+
use rustc_hir::Expr;
5+
use rustc_hir::ExprKind;
6+
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_session::{declare_tool_lint, impl_lint_pass};
8+
use rustc_span::sym;
9+
10+
declare_clippy_lint! {
11+
/// ### What it does
12+
/// Checks for the inclusion of large files via `include_bytes!()`
13+
/// and `include_str!()`
14+
///
15+
/// ### Why is this bad?
16+
/// Including large files can increase the size of the binary
17+
///
18+
/// ### Example
19+
/// ```rust,ignore
20+
/// let include = include_str!("very_large_file.txt");
21+
/// ```
22+
#[clippy::version = "1.62.0"]
23+
pub LARGE_INCLUDE_FILE,
24+
restriction,
25+
"including a large file"
26+
}
27+
28+
pub struct LargeIncludeFile {
29+
max_file_size: u64,
30+
}
31+
32+
impl LargeIncludeFile {
33+
#[must_use]
34+
pub fn new(max_file_size: u64) -> Self {
35+
Self { max_file_size }
36+
}
37+
}
38+
39+
impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);
40+
41+
impl LateLintPass<'_> for LargeIncludeFile {
42+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
43+
if_chain! {
44+
if let Some(macro_call) = root_macro_call_first_node(cx, expr);
45+
if cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
46+
|| cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id);
47+
if let ExprKind::Lit(lit) = &expr.kind;
48+
then {
49+
let len = match &lit.node {
50+
// include_bytes
51+
LitKind::ByteStr(bstr) => bstr.len(),
52+
// include_str
53+
LitKind::Str(sym, _) => sym.as_str().len(),
54+
_ => return,
55+
};
56+
57+
if len as u64 <= self.max_file_size {
58+
return;
59+
}
60+
61+
span_lint_and_help(
62+
cx,
63+
LARGE_INCLUDE_FILE,
64+
expr.span,
65+
"attempted to include a large file",
66+
None,
67+
&format!(
68+
"this lint is configured with a maximum size of {} bytes",
69+
self.max_file_size
70+
),
71+
);
72+
}
73+
}
74+
}
75+
}

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ store.register_lints(&[
209209
iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
210210
large_const_arrays::LARGE_CONST_ARRAYS,
211211
large_enum_variant::LARGE_ENUM_VARIANT,
212+
large_include_file::LARGE_INCLUDE_FILE,
212213
large_stack_arrays::LARGE_STACK_ARRAYS,
213214
len_zero::COMPARISON_TO_EMPTY,
214215
len_zero::LEN_WITHOUT_IS_EMPTY,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
2727
LintId::of(indexing_slicing::INDEXING_SLICING),
2828
LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
2929
LintId::of(integer_division::INTEGER_DIVISION),
30+
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
3031
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
3132
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
3233
LintId::of(map_err_ignore::MAP_ERR_IGNORE),

clippy_lints/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ mod items_after_statements;
262262
mod iter_not_returning_iterator;
263263
mod large_const_arrays;
264264
mod large_enum_variant;
265+
mod large_include_file;
265266
mod large_stack_arrays;
266267
mod len_zero;
267268
mod let_if_seq;
@@ -884,6 +885,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
884885
store.register_early_pass(|| Box::new(pub_use::PubUse));
885886
store.register_late_pass(|| Box::new(format_push_string::FormatPushString));
886887
store.register_late_pass(|| Box::new(bytes_count_to_len::BytesCountToLen));
888+
let max_include_file_size = conf.max_include_file_size;
889+
store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
887890
// add lints here, do not remove this comment, it's used in `new_lint`
888891
}
889892

clippy_lints/src/utils/conf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ define_Conf! {
312312
(max_suggested_slice_pattern_length: u64 = 3),
313313
/// Lint: AWAIT_HOLDING_INVALID_TYPE
314314
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedType> = Vec::new()),
315+
/// Lint: LARGE_INCLUDE_FILE.
316+
///
317+
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
318+
(max_include_file_size: u64 = 1_000_000),
315319
}
316320

317321
/// Search for the configuration file.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
max-include-file-size = 400
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![warn(clippy::large_include_file)]
2+
3+
// Good
4+
const GOOD_INCLUDE_BYTES: &[u8; 354] = include_bytes!("large_include_file.rs");
5+
const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");
6+
7+
// Bad
8+
const TOO_BIG_INCLUDE_BYTES: &[u8; 571] = include_bytes!("too_big.txt");
9+
const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
10+
11+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: attempted to include a large file
2+
--> $DIR/large_include_file.rs:8:43
3+
|
4+
LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 571] = include_bytes!("too_big.txt");
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::large-include-file` implied by `-D warnings`
8+
= help: this lint is configured with a maximum size of 400 bytes
9+
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
10+
11+
error: attempted to include a large file
12+
--> $DIR/large_include_file.rs:9:35
13+
|
14+
LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= help: this lint is configured with a maximum size of 400 bytes
18+
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
19+
20+
error: aborting due to 2 previous errors
21+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ultricies mi quis hendrerit dolor. Sit amet tellus cras adipiscing enim eu turpis egestas. Faucibus nisl tincidunt eget nullam non nisi est. Ipsum faucibus vitae aliquet nec ullamcorper sit. Maecenas pharetra convallis posuere morbi leo urna. Purus in mollis nunc sed id semper. Sit amet tellus cras adipiscing enim eu turpis egestas. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque. Massa vitae tortor condimentum lacinia quis vel.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `third-party` at line 5 column 1
1+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `third-party` at line 5 column 1
22

33
error: aborting due to previous error
44

0 commit comments

Comments
 (0)