From df5c64c66d7009880bc39c8dd2f327e119f3c6b3 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Tue, 12 Sep 2023 21:25:36 +0200 Subject: [PATCH] fix: use an `IndexMap` instead of `HashMap` for storing rule patterns This allows iterating over the patterns in the order they are declared in the rule. --- yara-x/src/compiler/context.rs | 15 ++++++++++++--- yara-x/src/compiler/mod.rs | 3 +-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/yara-x/src/compiler/context.rs b/yara-x/src/compiler/context.rs index 6aac69cf9..f321bde2e 100644 --- a/yara-x/src/compiler/context.rs +++ b/yara-x/src/compiler/context.rs @@ -1,8 +1,9 @@ use std::collections::VecDeque; +use std::hash::BuildHasherDefault; use std::mem::size_of; use std::rc::Rc; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHasher}; use walrus::ir::InstrSeqId; use walrus::{FunctionId, ValType}; use yara_x_parser::report::ReportBuilder; @@ -49,8 +50,16 @@ pub(in crate::compiler) struct Context<'a, 'src, 'sym> { /// Rule that is being compiled. pub current_rule: &'a RuleInfo, - /// IR nodes for patterns defined in the rule being compiled. - pub current_rule_patterns: &'a mut FxHashMap>, + /// IR nodes for patterns defined in the rule being compiled. This is an + /// [`IndexMap`] where keys are [`PatternId`]s and values are + /// [`ir::Pattern`]. A `IndexMap` is used instead of `HashMap` because + /// we want to be able to iterate over the patterns in the order they + /// were defined in the rule. + pub current_rule_patterns: &'a mut indexmap::IndexMap< + PatternId, + ir::Pattern<'src>, + BuildHasherDefault, + >, /// Warnings generated during the compilation. pub warnings: &'a mut Vec, diff --git a/yara-x/src/compiler/mod.rs b/yara-x/src/compiler/mod.rs index 7f4ab2d3d..3f6f7fba4 100644 --- a/yara-x/src/compiler/mod.rs +++ b/yara-x/src/compiler/mod.rs @@ -567,8 +567,7 @@ impl<'a> Compiler<'a> { let mut ident_and_pattern_ids = Vec::with_capacity(num_patterns); // Create a map (IdentId, Pattern). - let mut patterns_map: FxHashMap = - FxHashMap::default(); + let mut patterns_map = indexmap::IndexMap::default(); for (pattern_id, pattern) in iter::zip(self.next_pattern_id.successors(), patterns)