yara_x/compiler/
errors.rs

1#![cfg_attr(any(), rustfmt::skip)]
2#![allow(clippy::duplicated_attributes)]
3
4use std::fmt::{Debug, Display, Formatter};
5use std::io;
6use serde::Serialize;
7
8use thiserror::Error;
9
10use yara_x_macros::ErrorEnum;
11use yara_x_macros::ErrorStruct;
12use yara_x_parser::ast;
13
14use crate::compiler::report::{Level, Patch, Report, ReportBuilder, CodeLoc, Label, Footer};
15
16/// Error returned by [`crate::Compiler::emit_wasm_file`].
17#[derive(Error, Debug)]
18#[error(transparent)]
19#[doc(hidden)]
20pub struct EmitWasmError(#[from] anyhow::Error);
21
22/// Error returned by [`crate::Compiler::switch_warning`] when the warning
23/// code is not valid.
24#[derive(Error, Debug, Eq, PartialEq)]
25#[error("`{0}` is not a valid warning code")]
26pub struct InvalidWarningCode(String);
27
28impl InvalidWarningCode {
29    pub(crate) fn new(code: String) -> Self {
30        Self(code)
31    }
32}
33
34/// Error returned while serializing/deserializing compiled rules.
35#[derive(Error, Debug)]
36pub enum SerializationError {
37    /// The data being deserialized doesn't contain YARA-X serialized rules.
38    #[error("not a YARA-X compiled rules file")]
39    InvalidFormat,
40
41    /// Error occurred while encoding YARA-X rules.
42    #[error("cannot encode YARA-X rules")]
43    EncodeError(#[from] bincode::error::EncodeError),
44
45    /// Error occurred while decoding YARA-X rules.
46    #[error("cannot decode YARA-X rules")]
47    DecodeError(#[from] bincode::error::DecodeError),
48
49    /// I/O error while trying to read or write serialized data.
50    #[error(transparent)]
51    IoError(#[from] io::Error),
52
53    /// Error occurred while deserializing WASM code.
54    #[error("invalid YARA-X compiled rules file")]
55    InvalidWASM(#[from] anyhow::Error),
56}
57
58/// Error returned when rule compilation fails.
59#[allow(missing_docs)]
60#[non_exhaustive]
61#[derive(ErrorEnum, Error, Clone, PartialEq, Eq)]
62#[derive(Serialize)]
63#[serde(tag = "type")]
64pub enum CompileError {
65    ArbitraryRegexpPrefix(Box<ArbitraryRegexpPrefix>),
66    AssignmentMismatch(Box<AssignmentMismatch>),
67    CircularIncludes(Box<CircularIncludes>),
68    ConflictingRuleIdentifier(Box<ConflictingRuleIdentifier>),
69    CustomError(Box<CustomError>),
70    DuplicateModifier(Box<DuplicateModifier>),
71    DuplicatePattern(Box<DuplicatePattern>),
72    DuplicateRule(Box<DuplicateRule>),
73    DuplicateTag(Box<DuplicateTag>),
74    EmptyPatternSet(Box<EmptyPatternSet>),
75    EntrypointUnsupported(Box<EntrypointUnsupported>),
76    IncludeError(Box<IncludeError>),
77    IncludeNotAllowed(Box<IncludeNotAllowed>),
78    IncludeNotFound(Box<IncludeNotFound>),
79    InvalidBase64Alphabet(Box<InvalidBase64Alphabet>),
80    InvalidEscapeSequence(Box<InvalidEscapeSequence>),
81    InvalidFloat(Box<InvalidFloat>),
82    InvalidInteger(Box<InvalidInteger>),
83    InvalidMetadata(Box<InvalidMetadata>),
84    InvalidModifier(Box<InvalidModifier>),
85    InvalidModifierCombination(Box<InvalidModifierCombination>),
86    InvalidPattern(Box<InvalidPattern>),
87    InvalidRange(Box<InvalidRange>),
88    InvalidRegexp(Box<InvalidRegexp>),
89    InvalidRegexpModifier(Box<InvalidRegexpModifier>),
90    InvalidRuleName(Box<InvalidRuleName>),
91    InvalidTag(Box<InvalidTag>),
92    InvalidUTF8(Box<InvalidUTF8>),
93    MethodNotAllowedInWith(Box<MethodNotAllowedInWith>),
94    MismatchingTypes(Box<MismatchingTypes>),
95    MissingMetadata(Box<MissingMetadata>),
96    MixedGreediness(Box<MixedGreediness>),
97    NumberOutOfRange(Box<NumberOutOfRange>),
98    PotentiallySlowLoop(Box<PotentiallySlowLoop>),
99    SlowPattern(Box<SlowPattern>),
100    SyntaxError(Box<SyntaxError>),
101    TooManyPatterns(Box<TooManyPatterns>),
102    UnexpectedEscapeSequence(Box<UnexpectedEscapeSequence>),
103    UnexpectedNegativeNumber(Box<UnexpectedNegativeNumber>),
104    UnknownField(Box<UnknownField>),
105    UnknownIdentifier(Box<UnknownIdentifier>),
106    UnknownModule(Box<UnknownModule>),
107    UnknownPattern(Box<UnknownPattern>),
108    UnknownTag(Box<UnknownTag>),
109    UnusedPattern(Box<UnusedPattern>),
110    WrongArguments(Box<WrongArguments>),
111    WrongType(Box<WrongType>),
112}
113
114impl CompileError {
115    pub(crate) fn from(
116        report_builder: &ReportBuilder,
117        err: ast::Error,
118    ) -> Self {
119        match err {
120            ast::Error::SyntaxError { message, span } => {
121                SyntaxError::build(report_builder, message, report_builder.span_to_code_loc(span))
122            }
123            ast::Error::InvalidInteger { message, span } => {
124                InvalidInteger::build(report_builder, message, report_builder.span_to_code_loc(span))
125            }
126            ast::Error::InvalidFloat { message, span } => {
127                InvalidFloat::build(report_builder, message, report_builder.span_to_code_loc(span))
128            }
129            ast::Error::InvalidRegexpModifier { message, span } => {
130                InvalidRegexpModifier::build(
131                    report_builder,
132                    message,
133                    report_builder.span_to_code_loc(span),
134                )
135            }
136            ast::Error::InvalidEscapeSequence { message, span } => {
137                InvalidEscapeSequence::build(
138                    report_builder,
139                    message,
140                    report_builder.span_to_code_loc(span),
141                )
142            }
143            ast::Error::UnexpectedEscapeSequence(span) => {
144                UnexpectedEscapeSequence::build(report_builder, report_builder.span_to_code_loc(span))
145            }
146            ast::Error::InvalidUTF8(span) => {
147                InvalidUTF8::build(report_builder, report_builder.span_to_code_loc(span))
148            }
149        }
150    }
151
152    /// Utility function that receives an array of strings and joins them
153    /// together separated by commas and with "or" before the last one.
154    /// For example, if input is `["s1", "s2", "s3"]` the result is:
155    ///
156    /// ```text
157    /// str1, str2 or str3
158    /// ```
159    ///
160    /// If `quotes` is true, the strings are enclosed in back tilts, like this:
161    ///
162    /// ```text
163    /// `str1`, `str2` or `str3`
164    /// ```
165    ///
166    pub(crate) fn join_with_or<S: ToString>(s: &[S], quotes: bool) -> String {
167        let mut strings = if quotes {
168            s.iter()
169                .map(|s| format!("`{}`", s.to_string()))
170                .collect::<Vec<String>>()
171        } else {
172            s.iter().map(|s| s.to_string()).collect::<Vec<String>>()
173        };
174
175        // Sort alphabetically.
176        strings.sort();
177
178        // Deduplicate repeated items.
179        strings.dedup();
180
181        match strings.len() {
182            1 => strings[0].to_owned(),
183            2 => format!("{} or {}", strings[0], strings[1]),
184            l => {
185                format!(
186                    "{}, or {}",
187                    strings[..l - 1].join(", "),
188                    strings[l - 1]
189                )
190            }
191        }
192    }
193}
194
195/// A syntax error was found in the rule.
196#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
197#[associated_enum(CompileError)]
198#[error(code = "E001", title = "syntax error")]
199#[label("{error}", error_loc)]
200pub struct SyntaxError {
201    report: Report,
202    error: String,
203    error_loc: CodeLoc,
204}
205
206/// Some expression has an unexpected type.
207#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
208#[associated_enum(CompileError)]
209#[error(code = "E002", title = "wrong type")]
210#[label(
211    "expression should be {expected_types}, but it is {actual_type}",
212    error_loc
213)]
214#[footer(help, Level::HELP)]
215pub struct WrongType {
216    report: Report,
217    expected_types: String,
218    actual_type: String,
219    error_loc: CodeLoc,
220    help: Option<String>,
221}
222
223/// Operands have mismatching types.
224#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
225#[associated_enum(CompileError)]
226#[error(code = "E003", title = "mismatching types")]
227#[label("this expression is `{type1}`", type1_loc)]
228#[label("this expression is `{type2}`", type2_loc)]
229pub struct MismatchingTypes {
230    report: Report,
231    type1: String,
232    type2: String,
233    type1_loc: CodeLoc,
234    type2_loc: CodeLoc,
235}
236
237/// Wrong arguments when calling a function.
238#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
239#[associated_enum(CompileError)]
240#[error(code = "E004", title = "wrong arguments")]
241#[label("wrong arguments in this call", error_loc)]
242#[footer(note)]
243pub struct WrongArguments {
244    report: Report,
245    error_loc: CodeLoc,
246    note: Option<String>,
247}
248
249/// Mismatch between number of variables and number of values in a loop
250/// expression.
251#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
252#[associated_enum(CompileError)]
253#[error(code = "E005", title = "assignment mismatch")]
254#[label("this expects {expected_values} value(s)", error_loc)]
255#[label("this produces {actual_values} value(s)", iterable_loc)]
256pub struct AssignmentMismatch {
257    report: Report,
258    expected_values: u8,
259    actual_values: u8,
260    iterable_loc: CodeLoc,
261    error_loc: CodeLoc,
262}
263
264/// Negative number used where positive number was expected.
265#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
266#[associated_enum(CompileError)]
267#[error(code = "E006", title = "unexpected negative number")]
268#[label("this number can not be negative", error_loc)]
269pub struct UnexpectedNegativeNumber {
270    report: Report,
271    error_loc: CodeLoc,
272}
273
274/// A number is out of the allowed range.
275#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
276#[associated_enum(CompileError)]
277#[error(code = "E007", title = "number out of range")]
278#[label("this number is out of the allowed range [{min}-{max}]", error_loc)]
279pub struct NumberOutOfRange {
280    report: Report,
281    min: i64,
282    max: i64,
283    error_loc: CodeLoc,
284}
285
286/// Unknown field or method name.
287#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
288#[associated_enum(CompileError)]
289#[error(code = "E008", title = "unknown field or method `{identifier}`")]
290#[label("this field or method doesn't exist", error_loc)]
291pub struct UnknownField {
292    report: Report,
293    identifier: String,
294    error_loc: CodeLoc,
295}
296
297/// Unknown identifier.
298#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
299#[associated_enum(CompileError)]
300#[error(code = "E009", title = "unknown identifier `{identifier}`")]
301#[label("this identifier has not been declared", identifier_loc)]
302#[footer(note)]
303pub struct UnknownIdentifier {
304    report: Report,
305    identifier: String,
306    identifier_loc: CodeLoc,
307    note: Option<String>,
308}
309
310impl UnknownIdentifier {
311    /// Name of the unknown identifier.
312    #[inline]
313    pub fn identifier(&self) -> &str {
314        self.identifier.as_str()
315    }
316    /// Location of the unknown identifier.
317    pub(crate) fn identifier_location(&self) -> &CodeLoc {
318        &self.identifier_loc
319    }
320}
321
322/// Unknown module.
323#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
324#[associated_enum(CompileError)]
325#[error(code = "E010", title = "unknown module `{identifier}`")]
326#[label("module `{identifier}` not found", error_loc)]
327pub struct UnknownModule {
328    report: Report,
329    identifier: String,
330    error_loc: CodeLoc,
331}
332
333/// Invalid range.
334#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
335#[associated_enum(CompileError)]
336#[error(code = "E011", title = "invalid range")]
337#[label("{error}", error_loc)]
338pub struct InvalidRange {
339    report: Report,
340    error: String,
341    error_loc: CodeLoc,
342}
343
344/// Two rules have the same name.
345#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
346#[associated_enum(CompileError)]
347#[error(code = "E012", title = "duplicate rule `{new_rule}`")]
348#[label(
349    "duplicate declaration of `{new_rule}`",
350    duplicate_rule_loc,
351    Level::ERROR
352)]
353#[label(
354    "`{new_rule}` declared here for the first time",
355    existing_rule_loc,
356    Level::NOTE
357)]
358pub struct DuplicateRule {
359    report: Report,
360    new_rule: String,
361    duplicate_rule_loc: CodeLoc,
362    existing_rule_loc: CodeLoc,
363}
364
365
366/// A rule has the same name as a module or global variable.
367#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
368#[associated_enum(CompileError)]
369#[error(
370    code = "E013",
371    title = "rule `{identifier}` conflicts with an existing identifier"
372)]
373#[label("identifier already in use by a module or global variable", error_loc)]
374pub struct ConflictingRuleIdentifier {
375    report: Report,
376    identifier: String,
377    error_loc: CodeLoc,
378}
379
380/// A regular expression is invalid.
381#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
382#[associated_enum(CompileError)]
383#[error(code = "E014", title = "invalid regular expression")]
384#[label("{error}", error_loc)]
385#[footer(note)]
386pub struct InvalidRegexp {
387    report: Report,
388    error: String,
389    error_loc: CodeLoc,
390    note: Option<String>,
391}
392
393/// A regular expression contains a mixture of greedy and non-greedy quantifiers.
394#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
395#[associated_enum(CompileError)]
396#[error(
397    code = "E015",
398    title = "mixing greedy and non-greedy quantifiers in regular expression"
399)]
400#[label("this is {quantifier1_greediness}", quantifier1_loc)]
401#[label("this is {quantifier2_greediness}", quantifier2_loc)]
402pub struct MixedGreediness {
403    report: Report,
404    quantifier1_greediness: String,
405    quantifier2_greediness: String,
406    quantifier1_loc: CodeLoc,
407    quantifier2_loc: CodeLoc,
408}
409
410/// A set of patterns doesn't contain any patterns.
411#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
412#[associated_enum(CompileError)]
413#[error(code = "E016", title = "no matching patterns")]
414#[label("there's no pattern in this set", error_loc)]
415#[footer(note)]
416pub struct EmptyPatternSet {
417    report: Report,
418    error_loc: CodeLoc,
419    note: Option<String>,
420}
421
422/// The `entrypoint` keyword is not supported.
423#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
424#[associated_enum(CompileError)]
425#[error(code = "E017", title = "`entrypoint` is unsupported")]
426#[label("the `entrypoint` keyword is not supported anymore", error_loc)]
427pub struct EntrypointUnsupported {
428    report: Report,
429    error_loc: CodeLoc,
430}
431
432/// Some pattern may be potentially slow.
433#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
434#[associated_enum(CompileError)]
435#[error(code = "E018", title = "slow pattern")]
436#[label("this pattern may slow down the scan", error_loc)]
437#[footer(note)]
438pub struct SlowPattern {
439    report: Report,
440    error_loc: CodeLoc,
441    note: Option<String>,
442}
443
444/// A pattern has modifiers that can't be used together.
445#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
446#[associated_enum(CompileError)]
447#[error(
448    code = "E019",
449    title = "invalid modifier combination: `{modifier1}` `{modifier2}`"
450)]
451#[label("`{modifier1}` modifier used here", modifier1_loc)]
452#[label("`{modifier2}` modifier used here", modifier2_loc)]
453#[footer(note)]
454pub struct InvalidModifierCombination {
455    report: Report,
456    modifier1: String,
457    modifier2: String,
458    modifier1_loc: CodeLoc,
459    modifier2_loc: CodeLoc,
460    note: Option<String>,
461}
462
463/// A pattern has duplicate modifiers.
464#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
465#[associated_enum(CompileError)]
466#[error(code = "E020", title = "duplicate pattern modifier")]
467#[label("duplicate modifier", error_loc)]
468pub struct DuplicateModifier {
469    report: Report,
470    error_loc: CodeLoc,
471}
472
473/// A rule has duplicate tags.
474#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
475#[associated_enum(CompileError)]
476#[error(code = "E021", title = "duplicate tag `{tag}`")]
477#[label("duplicate tag", error_loc)]
478pub struct DuplicateTag {
479    report: Report,
480    tag: String,
481    error_loc: CodeLoc,
482}
483
484/// A rule defines a pattern that is not used in the condition.
485#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
486#[associated_enum(CompileError)]
487#[error(code = "E022", title = "unused pattern `{pattern_ident}`")]
488#[label("this pattern was not used in the condition", error_loc)]
489pub struct UnusedPattern {
490    report: Report,
491    pattern_ident: String,
492    error_loc: CodeLoc,
493}
494
495/// A rule has two patterns with the same identifier.
496#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
497#[associated_enum(CompileError)]
498#[error(code = "E023", title = "duplicate pattern `{pattern_ident}`")]
499#[label("duplicate declaration of `{pattern_ident}`", error_loc)]
500#[label(
501    "`{pattern_ident}` declared here for the first time",
502    note_loc,
503    Level::NOTE
504)]
505pub struct DuplicatePattern {
506    report: Report,
507    pattern_ident: String,
508    error_loc: CodeLoc,
509    note_loc: CodeLoc,
510}
511
512/// A rule has an invalid pattern.
513#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
514#[associated_enum(CompileError)]
515#[error(code = "E024", title = "invalid pattern `{pattern_ident}`")]
516#[label("{error}", error_loc)]
517#[footer(note)]
518pub struct InvalidPattern {
519    report: Report,
520    pattern_ident: String,
521    error: String,
522    error_loc: CodeLoc,
523    note: Option<String>,
524}
525
526/// Some rule condition uses a pattern that was not defined.
527#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
528#[associated_enum(CompileError)]
529#[error(code = "E025", title = "unknown pattern `{pattern_ident}`")]
530#[label("this pattern is not declared in the `strings` section", error_loc)]
531pub struct UnknownPattern {
532    report: Report,
533    pattern_ident: String,
534    error_loc: CodeLoc,
535}
536
537/// Wrong alphabet for the `base64` or `base64wide` modifiers.
538#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
539#[associated_enum(CompileError)]
540#[error(code = "E026", title = "invalid base64 alphabet")]
541#[label("{error}", error_loc)]
542pub struct InvalidBase64Alphabet {
543    report: Report,
544    error: String,
545    error_loc: CodeLoc,
546}
547
548/// Invalid integer.
549#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
550#[associated_enum(CompileError)]
551#[error(code = "E027", title = "invalid integer")]
552#[label("{error}", error_loc)]
553pub struct InvalidInteger {
554    report: Report,
555    error: String,
556    error_loc: CodeLoc,
557}
558
559/// Invalid float.
560#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
561#[associated_enum(CompileError)]
562#[error(code = "E028", title = "invalid float")]
563#[label("{error}", error_loc)]
564pub struct InvalidFloat {
565    report: Report,
566    error: String,
567    error_loc: CodeLoc,
568}
569
570/// A text pattern contains an invalid escape sequence.
571#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
572#[associated_enum(CompileError)]
573#[error(code = "E029", title = "invalid escape sequence")]
574#[label("{error}", error_loc)]
575pub struct InvalidEscapeSequence {
576    report: Report,
577    error: String,
578    error_loc: CodeLoc,
579}
580
581/// Invalid modifier for a regular expression.
582#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
583#[associated_enum(CompileError)]
584#[error(code = "E030", title = "invalid regexp modifier `{modifier}`")]
585#[label("invalid modifier", error_loc)]
586pub struct InvalidRegexpModifier {
587    report: Report,
588    modifier: String,
589    error_loc: CodeLoc,
590}
591
592/// A string literal contains escaped sequences and it shouldn't.
593#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
594#[associated_enum(CompileError)]
595#[error(code = "E031", title = "unexpected escape sequence")]
596#[label("escape sequences are not allowed in this string", error_loc)]
597pub struct UnexpectedEscapeSequence {
598    report: Report,
599    error_loc: CodeLoc,
600}
601
602
603/// Source code contains invalid UTF-8 characters.
604#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
605#[associated_enum(CompileError)]
606#[error(code = "E032", title = "invalid UTF-8")]
607#[label("invalid UTF-8 character", error_loc)]
608pub struct InvalidUTF8 {
609    report: Report,
610    error_loc: CodeLoc,
611}
612
613/// Some pattern has an invalid modifier.
614#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
615#[associated_enum(CompileError)]
616#[error(code = "E033", title = "invalid pattern modifier")]
617#[label("{error}", error_loc)]
618pub struct InvalidModifier {
619    report: Report,
620    error: String,
621    error_loc: CodeLoc,
622}
623
624/// A rule contains a loop that could be very slow.
625///
626/// This error indicates that a rule contains a `for` loop that may be very
627/// slow because it iterates over a range with an upper bound that depends on
628/// `filesize`. For very large files this may mean hundreds of millions of
629/// iterations.
630///
631/// # Example
632///
633/// ```text
634/// error[E034]: potentially slow loop
635///  --> test.yar:1:34
636///   |
637/// 1 | rule t { condition: for any i in (0..filesize-1) : ( int32(i) == 0xcafebabe ) }
638///   |                                  --------------- this range can be very large
639///   |
640/// ```
641#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
642#[associated_enum(CompileError)]
643#[error(code = "E034", title = "potentially slow loop")]
644#[label(
645"this range can be very large",
646    loc
647)]
648pub struct PotentiallySlowLoop {
649    report: Report,
650    loc: CodeLoc,
651}
652
653/// A rule has too many patterns.
654#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
655#[associated_enum(CompileError)]
656#[error(code = "E035", title = "too many patterns in a rule")]
657#[label("this rule has more than {max_num_patterns} patterns", error_loc)]
658pub struct TooManyPatterns {
659    report: Report,
660    max_num_patterns: usize,
661    error_loc: CodeLoc,
662}
663
664/// A rule has too many patterns.
665#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
666#[associated_enum(CompileError)]
667#[error(code = "E036", title = "method not allowed in `with` statement")]
668#[label("this method is not allowed here", error_loc)]
669pub struct MethodNotAllowedInWith {
670    report: Report,
671    error_loc: CodeLoc,
672}
673
674/// Some metadata entry is invalid. This is only used if the compiler is
675/// configured to check for valid metadata (see: [`crate::linters::Metadata`]).
676///
677/// ## Example
678///
679/// ```text
680/// error[E037]: metadata `author` is not valid
681/// --> test.yar:4:5
682///   |
683/// 4 |     author = 1234
684///   |              ---- `author` must be a string
685///   |
686/// ```
687#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
688#[associated_enum(CompileError)]
689#[error(code = "E037", title = "metadata `{name}` is not valid")]
690#[label(
691    "{label}",
692    label_loc
693)]
694pub struct InvalidMetadata {
695    report: Report,
696    name: String,
697    label_loc: CodeLoc,
698    label: String,
699}
700
701/// Missing metadata. This is only used if the compiler is configured to check
702/// for required metadata (see:  [`crate::linters::Metadata`]).
703///
704/// ## Example
705///
706/// ```text
707/// error[E038]: required metadata is missing
708///  --> test.yar:12:6
709///    |
710/// 12 | rule pants {
711///    |      ----- required metadata "date" not found
712///    |
713/// ```
714#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
715#[associated_enum(CompileError)]
716#[error(
717    code = "E038",
718    title = "required metadata is missing"
719)]
720#[label(
721    "required metadata `{name}` not found",
722    rule_loc
723)]
724#[footer(note)]
725pub struct MissingMetadata {
726    report: Report,
727    rule_loc: CodeLoc,
728    name: String,
729    note: Option<String>,
730}
731
732/// Rule name does not match regex. This is only used if the compiler is
733/// configured to check for it (see: [`crate::linters::RuleName`]).
734///
735/// ## Example
736///
737/// ```text
738/// error[E039]: rule name does not match regex `APT_.*`
739///  --> test.yar:13:6
740///    |
741/// 13 | rule pants {
742///    |      ----- this rule name does not match regex `APT_.*`
743///    |
744/// ```
745#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
746#[associated_enum(CompileError)]
747#[error(
748    code = "E039",
749    title = "rule name does not match regex `{regex}`"
750)]
751#[label(
752    "this rule name does not match regex `{regex}`",
753    rule_loc
754)]
755pub struct InvalidRuleName {
756    report: Report,
757    rule_loc: CodeLoc,
758    regex: String,
759}
760
761/// Unknown tag. This is only used if the compiler is configured to check
762/// for required tags (see:  [`crate::linters::Tags`]).
763///
764/// ## Example
765///
766/// ```text
767/// error[E040]: tag not in allowed list
768///  --> rules/test.yara:1:10
769///   |
770/// 1 | rule a : foo {
771///   |          ^^^ tag `foo` not in allowed list
772///   |
773///   = note: Allowed tags: test, bar
774/// ```
775#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
776#[associated_enum(CompileError)]
777#[error(
778    code = "E040",
779    title = "tag not in allowed list"
780)]
781#[label(
782    "tag `{name}` not in allowed list",
783    tag_loc
784)]
785#[footer(note)]
786pub struct UnknownTag {
787    report: Report,
788    tag_loc: CodeLoc,
789    name: String,
790    note: Option<String>,
791}
792
793/// Tag does not match regex. This is only used if the compiler is configured to
794/// check for it (see: [`crate::linters::Tags`]).
795///
796/// ## Example
797///
798/// ```text
799/// error[E041]: tag does not match regex `bar`
800///  --> rules/test.yara:1:10
801///   |
802/// 1 | rule a : foo {
803///   |          ^^^ tag `foo` does not match regex `bar`
804///   |
805/// ```
806#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
807#[associated_enum(CompileError)]
808#[error(
809    code = "E041",
810    title = "tag does not match regex `{regex}`"
811)]
812#[label(
813    "tag `{name}` does not match regex `{regex}`",
814    tag_loc
815)]
816pub struct InvalidTag {
817    report: Report,
818    tag_loc: CodeLoc,
819    name: String,
820    regex: String,
821}
822
823/// An error occurred while including a file.
824///
825/// ## Example
826///
827/// ```text
828/// error[E042]: error including file
829///  --> line:1:1
830///   |
831/// 1 | include "unknown"
832///   | ^^^^^^^^^^^^^^^^^ failed with error: Permission denied (os error 13)
833///   |
834/// ```
835#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
836#[associated_enum(CompileError)]
837#[error(
838    code = "E042",
839    title = "error including file"
840)]
841#[label(
842    "failed with error: {error}",
843    include_loc
844)]
845pub struct IncludeError {
846    report: Report,
847    include_loc: CodeLoc,
848    error: String,
849}
850
851/// An included file was not found.
852///
853/// ## Example
854///
855/// ```text
856/// error[E042]: include file not found
857///  --> line:1:1
858///   |
859/// 1 | include "unknown"
860///   | ^^^^^^^^^^^^^^^^^ `unknown` not found in any of the include directories
861///   |
862/// ```
863#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
864#[associated_enum(CompileError)]
865#[error(
866    code = "E043",
867    title = "include file not found"
868)]
869#[label(
870    "`{file_path}` not found in any of the include directories",
871    include_loc
872)]
873pub struct IncludeNotFound {
874    report: Report,
875    file_path: String,
876    include_loc: CodeLoc,
877}
878
879/// An include statement was used, but includes are disabled
880///
881/// # Example
882///
883/// ```text
884/// error[E044]: include statements not allowed
885///  --> line:1:1
886///
887/// 1 | include "some_file"
888///   | ^^^^^^^^^^^^^^^^^^^ includes are disabled for this compilation
889///   |
890/// ```
891#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
892#[associated_enum(CompileError)]
893#[error(
894    code = "E044",
895    title = "include statements not allowed"
896)]
897#[label(
898    "includes are disabled for this compilation",
899    include_loc
900)]
901pub struct IncludeNotAllowed {
902    report: Report,
903    include_loc: CodeLoc,
904}
905
906/// Indicates that a regular expression has a prefix that can be arbitrarily
907/// long and matches any sequence of bytes.
908///
909/// # Example
910///
911/// ```text
912/// error[E045]: arbitrary regular expression prefix  
913///  --> line:3:11  
914///   |  
915/// 3 |     $a = /.*foo/s  
916///   |           ^^ this prefix can be arbitrarily long and matches all bytes  
917///   |
918/// ```  
919///
920/// Regular expressions with such prefixes are problematic because YARA will
921/// report a match at every file offset from the start of the file up to where
922/// the rest of the pattern matches. In most cases, this prefix can be removed
923/// without affecting the rule's semantics.
924#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
925#[associated_enum(CompileError)]
926#[error(code = "E045", title = "arbitrary regular expression prefix")]
927#[label("this prefix can be arbitrarily long and matches all bytes", error_loc)]
928pub struct ArbitraryRegexpPrefix {
929    report: Report,
930    error_loc: CodeLoc,
931}
932
933/// Include statements have circular dependencies.
934#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
935#[associated_enum(CompileError)]
936#[error(code = "E046", title = "circular include dependencies")]
937#[label("include statement has circular dependencies", error_loc)]
938#[footer(note)]
939pub struct CircularIncludes {
940    report: Report,
941    error_loc: CodeLoc,
942    note: Option<String>,
943}
944
945/// A custom error has occurred.
946#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
947#[associated_enum(CompileError)]
948#[error(code = "E100", title = "{title}")]
949#[label("{error}", error_loc)]
950pub struct CustomError {
951    report: Report,
952    title: String,
953    error: String,
954    error_loc: CodeLoc,
955}