Skip to content

Commit

Permalink
fix: panic when update_time_spent_in_rule is called with an invalid…
Browse files Browse the repository at this point in the history
… `RuleId`

The `RuleId` passed to this function can be off by one.
  • Loading branch information
plusvic committed Oct 28, 2024
1 parent 3c46595 commit 86fb697
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
12 changes: 8 additions & 4 deletions lib/src/scanner/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,17 @@ impl ScanContext<'_> {
/// increased by the time elapsed since `rule_execution_start_time`.
#[cfg(feature = "rules-profiling")]
pub(crate) fn update_time_spent_in_rule(&mut self, rule_id: RuleId) {
self.time_spent_in_rule
.get_mut::<usize>(rule_id.into())
.unwrap()
.add_assign(self.clock.delta_as_nanos(
// The RuleId is not guaranteed to be a valid one. It may be larger
// than the last RuleId, so we can't assume that the `get_mut` will
// be successful.
if let Some(time_spend_in_rule) =
self.time_spent_in_rule.get_mut::<usize>(rule_id.into())
{
time_spend_in_rule.add_assign(self.clock.delta_as_nanos(
self.rule_execution_start_time,
self.clock.raw(),
));
}
}

/// Called during the scan process when a rule didn't match.
Expand Down
22 changes: 15 additions & 7 deletions lib/src/scanner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,13 +734,21 @@ impl<'r> Scanner<'r> {
#[cfg(feature = "rules-profiling")]
if func_result.is_err() {
let ctx = self.wasm_store.data_mut();
// When a timeout occurs, neither `ctx.track_rule_no_match` nor
// `ctx.track_rule_match` are invoked for the rule that was being
// executed at that moment. This implies that the time spent in
// that rule has not being updated yet, and we must do it here.
// The ID of the rule that was being executed is the one that
// comes after the last executed one. This assumes that rules are
// executed in strict ID increasing order.
// If a timeout occurs, the methods `ctx.track_rule_no_match` or
// `ctx.track_rule_match` may not be invoked for the currently
// executing rule. This means that the time spent within that rule
// has not been recorded yet, so we need to update it here.
//
// The ID of the rule that was running during the timeout can be
// determined as the one immediately following the last executed
// rule, based on the assumption that rules are processed in a
// strictly ascending ID order.
//
// Additionally, if the timeout happens after `ctx.last_executed_rule`
// has been updated with the last rule ID, we might end up calling
// `update_time_spent_in_rule` with an ID that is off by one.
// However, this function is designed to handle such cases
// gracefully.
ctx.update_time_spent_in_rule(
ctx.last_executed_rule
.map_or(RuleId::from(0), |rule_id| rule_id.next()),
Expand Down

0 comments on commit 86fb697

Please # to comment.