Skip to content

Commit

Permalink
Auto merge of #8727 - Serial-ATA:lint-large-includes, r=xFrednet
Browse files Browse the repository at this point in the history
Add `large_include_file` lint

changelog: Add [`large_include_file`] lint
closes #7005
  • Loading branch information
bors committed Apr 25, 2022
2 parents 388e6b7 + a85dc87 commit 760f293
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3478,6 +3478,7 @@ Released 2018-09-13
[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups
[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
[`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file
[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
Expand Down
86 changes: 86 additions & 0 deletions clippy_lints/src/large_include_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::is_lint_allowed;
use clippy_utils::macros::root_macro_call_first_node;
use rustc_ast::LitKind;
use rustc_hir::Expr;
use rustc_hir::ExprKind;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;

declare_clippy_lint! {
/// ### What it does
/// Checks for the inclusion of large files via `include_bytes!()`
/// and `include_str!()`
///
/// ### Why is this bad?
/// Including large files can increase the size of the binary
///
/// ### Example
/// ```rust,ignore
/// let included_str = include_str!("very_large_file.txt");
/// let included_bytes = include_bytes!("very_large_file.txt);
/// ```
///
/// Instead, you can load the file at runtime:
/// ```rust,ignore
/// use std::fs;
///
/// let string = fs::read_to_string("very_large_file.txt")?;
/// let bytes = fs::read("very_large_file.txt")?;
/// ```
#[clippy::version = "1.62.0"]
pub LARGE_INCLUDE_FILE,
restriction,
"including a large file"
}

pub struct LargeIncludeFile {
max_file_size: u64,
}

impl LargeIncludeFile {
#[must_use]
pub fn new(max_file_size: u64) -> Self {
Self { max_file_size }
}
}

impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);

impl LateLintPass<'_> for LargeIncludeFile {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
if_chain! {
if let Some(macro_call) = root_macro_call_first_node(cx, expr);
if !is_lint_allowed(cx, LARGE_INCLUDE_FILE, expr.hir_id);
if cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
|| cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id);
if let ExprKind::Lit(lit) = &expr.kind;
then {
let len = match &lit.node {
// include_bytes
LitKind::ByteStr(bstr) => bstr.len(),
// include_str
LitKind::Str(sym, _) => sym.as_str().len(),
_ => return,
};

if len as u64 <= self.max_file_size {
return;
}

span_lint_and_note(
cx,
LARGE_INCLUDE_FILE,
expr.span,
"attempted to include a large file",
None,
&format!(
"the configuration allows a maximum size of {} bytes",
self.max_file_size
),
);
}
}
}
}
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ store.register_lints(&[
iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
large_const_arrays::LARGE_CONST_ARRAYS,
large_enum_variant::LARGE_ENUM_VARIANT,
large_include_file::LARGE_INCLUDE_FILE,
large_stack_arrays::LARGE_STACK_ARRAYS,
len_zero::COMPARISON_TO_EMPTY,
len_zero::LEN_WITHOUT_IS_EMPTY,
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_restriction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
LintId::of(indexing_slicing::INDEXING_SLICING),
LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
LintId::of(integer_division::INTEGER_DIVISION),
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
LintId::of(map_err_ignore::MAP_ERR_IGNORE),
Expand Down
3 changes: 3 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ mod items_after_statements;
mod iter_not_returning_iterator;
mod large_const_arrays;
mod large_enum_variant;
mod large_include_file;
mod large_stack_arrays;
mod len_zero;
mod let_if_seq;
Expand Down Expand Up @@ -884,6 +885,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_early_pass(|| Box::new(pub_use::PubUse));
store.register_late_pass(|| Box::new(format_push_string::FormatPushString));
store.register_late_pass(|| Box::new(bytes_count_to_len::BytesCountToLen));
let max_include_file_size = conf.max_include_file_size;
store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
// add lints here, do not remove this comment, it's used in `new_lint`
}

Expand Down
4 changes: 4 additions & 0 deletions clippy_lints/src/utils/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ define_Conf! {
(max_suggested_slice_pattern_length: u64 = 3),
/// Lint: AWAIT_HOLDING_INVALID_TYPE
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedType> = Vec::new()),
/// Lint: LARGE_INCLUDE_FILE.
///
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
(max_include_file_size: u64 = 1_000_000),
}

/// Search for the configuration file.
Expand Down
1 change: 1 addition & 0 deletions tests/ui-toml/large_include_file/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
max-include-file-size = 600
16 changes: 16 additions & 0 deletions tests/ui-toml/large_include_file/large_include_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![warn(clippy::large_include_file)]

// Good
const GOOD_INCLUDE_BYTES: &[u8; 581] = include_bytes!("large_include_file.rs");
const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");

#[allow(clippy::large_include_file)]
const ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
#[allow(clippy::large_include_file)]
const ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");

// Bad
const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui-toml/large_include_file/large_include_file.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: attempted to include a large file
--> $DIR/large_include_file.rs:13:43
|
LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::large-include-file` implied by `-D warnings`
= note: the configuration allows a maximum size of 600 bytes
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)

error: attempted to include a large file
--> $DIR/large_include_file.rs:14:35
|
LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the configuration allows a maximum size of 600 bytes
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

1 change: 1 addition & 0 deletions tests/ui-toml/large_include_file/too_big.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Maecenas accumsan lacus vel facilisis volutpat. Etiam dignissim diam quis enim lobortis scelerisque fermentum dui faucibus. Tellus id interdum velit laoreet id donec ultrices. Est ultricies integer quis auctor elit sed vulputate. Erat velit scelerisque in dictum non consectetur a erat nam. Sed blandit libero volutpat sed. Tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae et leo duis. Congue mauris rhoncus aenean vel elit scelerisque. Id consectetur purus ut faucibus pulvinar elementum integer.
2 changes: 1 addition & 1 deletion tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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
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

error: aborting due to previous error

0 comments on commit 760f293

Please sign in to comment.