#![cfg_attr(any(), rustfmt::skip)]
#![allow(clippy::duplicated_attributes)]
use std::fmt::{Debug, Display, Formatter};
use serde::Serialize;
use thiserror::Error;
use yara_x_macros::ErrorEnum;
use yara_x_macros::ErrorStruct;
pub(crate) use crate::compiler::report::{Level, Patch, Report, ReportBuilder, CodeLoc, Label, Footer};
#[allow(missing_docs)]
#[non_exhaustive]
#[derive(ErrorEnum, Error, PartialEq, Eq)]
#[derive(Serialize)]
#[serde(tag = "type")]
pub enum Warning {
AmbiguousExpression(Box<AmbiguousExpression>),
BooleanIntegerComparison(Box<BooleanIntegerComparison>),
ConsecutiveJumps(Box<ConsecutiveJumps>),
DeprecatedField(Box<DeprecatedField>),
DuplicateImport(Box<DuplicateImport>),
GlobalRuleMisuse(Box<GlobalRuleMisuse>),
IgnoredModule(Box<IgnoredModule>),
IgnoredRule(Box<IgnoredRule>),
InvalidMetadata(Box<InvalidMetadata>),
InvalidRuleName(Box<InvalidRuleName>),
InvalidTag(Box<InvalidTag>),
InvariantBooleanExpression(Box<InvariantBooleanExpression>),
MissingMetadata(Box<MissingMetadata>),
NonBooleanAsBoolean(Box<NonBooleanAsBoolean>),
PotentiallySlowLoop(Box<PotentiallySlowLoop>),
PotentiallyUnsatisfiableExpression(Box<PotentiallyUnsatisfiableExpression>),
RedundantCaseModifier(Box<RedundantCaseModifier>),
SlowPattern(Box<SlowPattern>),
TextPatternAsHex(Box<TextPatternAsHex>),
TooManyIterations(Box<TooManyIterations>),
UnknownTag(Box<UnknownTag>),
UnsatisfiableExpression(Box<UnsatisfiableExpression>),
UnusedIdentifier(Box<UnusedIdentifier>),
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "consecutive_jumps",
title = "consecutive jumps in hex pattern `{pattern_ident}`",
)]
#[label(
"these consecutive jumps will be treated as {coalesced_jump}",
coalesced_jump_loc
)]
pub struct ConsecutiveJumps {
report: Report,
pattern_ident: String,
coalesced_jump: String,
coalesced_jump_loc: CodeLoc,
}
impl ConsecutiveJumps {
#[inline]
pub fn pattern(&self) -> &str {
self.pattern_ident.as_str()
}
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "potentially_slow_loop",
title = "potentially slow loop",
)]
#[label(
"this range can be very large",
loc
)]
pub struct PotentiallySlowLoop {
report: Report,
loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "unsatisfiable_expr",
title = "potentially unsatisfiable expression"
)]
#[label(
"this implies that multiple patterns must match",
quantifier_loc
)]
#[label(
"but they must match at the same offset",
at_loc
)]
pub struct PotentiallyUnsatisfiableExpression {
report: Report,
quantifier_loc: CodeLoc,
at_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "unsatisfiable_expr",
title = "unsatisfiable expression"
)]
#[label(
"{label_1}",
loc_1
)]
#[label(
"{label_2}",
loc_2
)]
#[footer(note)]
pub struct UnsatisfiableExpression {
report: Report,
label_1: String,
label_2: String,
loc_1: CodeLoc,
loc_2: CodeLoc,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "invariant_expr",
title = "invariant boolean expression"
)]
#[label(
"this expression is always {expr_value}",
expr_loc
)]
#[footer(note)]
pub struct InvariantBooleanExpression {
report: Report,
expr_value: bool,
expr_loc: CodeLoc,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "non_bool_expr",
title = "non-boolean expression used as boolean"
)]
#[label(
"this expression is `{expr_type}` but is being used as `bool`",
expr_loc
)]
#[footer(note)]
pub struct NonBooleanAsBoolean {
report: Report,
expr_type: String,
expr_loc: CodeLoc,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "bool_int_comparison",
title = "comparison between boolean and integer"
)]
#[label(
"this is comparing an integer and a boolean",
expr_loc
)]
pub struct BooleanIntegerComparison {
report: Report,
expr_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "duplicate_import",
title = "duplicate import statement"
)]
#[label(
"duplicate import",
new_import_loc
)]
#[label(
"`{module_name}` imported here for the first time",
existing_import_loc,
Level::NOTE
)]
pub struct DuplicateImport {
report: Report,
module_name: String,
new_import_loc: CodeLoc,
existing_import_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "redundant_modifier",
title = "redundant case-insensitive modifier"
)]
#[label(
"the `i` suffix indicates that the pattern is case-insensitive",
i_loc
)]
#[label(
"the `nocase` modifier does the same",
nocase_loc
)]
pub struct RedundantCaseModifier {
report: Report,
nocase_loc: CodeLoc,
i_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "slow_pattern",
title = "slow pattern"
)]
#[label(
"this pattern may slow down the scan",
pattern_loc
)]
#[footer(note)]
pub struct SlowPattern {
report: Report,
pattern_loc: CodeLoc,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "unsupported_module",
title = "module `{module_name}` is not supported"
)]
#[label(
"module `{module_name}` used here",
module_name_loc
)]
#[footer(note)]
pub struct IgnoredModule {
report: Report,
module_name: String,
module_name_loc: CodeLoc,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "ignored_rule",
title = "rule `{ignored_rule}` will be ignored due to an indirect dependency on module `{module_name}`"
)]
#[label(
"this other rule depends on module `{module_name}`, which is unsupported",
ignored_rule_loc
)]
pub struct IgnoredRule {
report: Report,
module_name: String,
ignored_rule: String,
ignored_rule_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "text_as_hex",
title = "hex pattern could be written as text literal"
)]
#[label(
"this pattern can be written as a text literal",
pattern_loc
)]
pub struct TextPatternAsHex {
report: Report,
pattern_loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "invalid_metadata",
title = "metadata `{name}` is not valid"
)]
#[label(
"{label}",
label_loc
)]
pub struct InvalidMetadata {
report: Report,
name: String,
label_loc: CodeLoc,
label: String,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "missing_metadata",
title = "required metadata is missing"
)]
#[label(
"required metadata `{name}` not found",
rule_loc
)]
#[footer(note)]
pub struct MissingMetadata {
report: Report,
rule_loc: CodeLoc,
name: String,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "invalid_rule_name",
title = "rule name does not match regex `{regex}`"
)]
#[label(
"this rule name does not match regex `{regex}`",
rule_loc
)]
pub struct InvalidRuleName {
report: Report,
rule_loc: CodeLoc,
regex: String,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "too_many_iterations",
title = "loop has too many iterations",
)]
#[label(
"this loop iterates {iterations} times, which may be slow",
loc
)]
pub struct TooManyIterations {
report: Report,
iterations: i64,
loc: CodeLoc,
}
#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "unknown_tag",
title = "tag not in allowed list"
)]
#[label(
"tag `{name}` not in allowed list",
tag_loc
)]
#[footer(note)]
pub struct UnknownTag {
report: Report,
tag_loc: CodeLoc,
name: String,
note: Option<String>,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "invalid_tag",
title = "tag `{name}` does not match regex `{regex}`"
)]
#[label(
"tag `{name}` does not match regex `{regex}`",
tag_loc
)]
pub struct InvalidTag {
report: Report,
tag_loc: CodeLoc,
name: String,
regex: String,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "deprecated_field",
title = "field `{name}` is deprecated"
)]
#[label(
"{msg}",
loc
)]
pub struct DeprecatedField {
report: Report,
name: String,
loc: CodeLoc,
msg: String,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "ambiguous_expr",
title = "ambiguous expression"
)]
#[label(
"this expression is ambiguous",
loc
)]
pub struct AmbiguousExpression {
report: Report,
loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "unused_identifier",
title = "unused identifier",
)]
#[label(
"this identifier declared but not used",
loc
)]
pub struct UnusedIdentifier {
report: Report,
loc: CodeLoc,
}
#[derive(ErrorStruct, Debug, PartialEq, Eq)]
#[associated_enum(Warning)]
#[warning(
code = "global_rule_misuse",
title = "global rule used in condition",
)]
#[label(
"a global rule is being used as part of an condition",
loc
)]
#[footer(note)]
pub struct GlobalRuleMisuse {
report: Report,
loc: CodeLoc,
note: Option<String>,
}