Skip to content

Commit

Permalink
Improve the limit adjustment logic and add safety checks
Browse files Browse the repository at this point in the history
If limits are calculated for f64 data that uses a RAT_FUNC compu method,
then the ration function will be applied to the input values f64::MIN
and f64::MAX. In this situation it is essential to divide first and then multiply.
Even then the result can be +/-INF, so a safety check has been added.
  • Loading branch information
DanielT committed Nov 11, 2024
1 parent abd85d5 commit 3cc9e35
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ fn adjust_limits(
// y = (bx + c) / f
// which can be inverted to
// x = (fy - c) / b
let func = |y: f64| (c.f * y - c.c) / c.b;
let func = |y: f64| (c.f / c.b) * y - (c.c / c.b);
new_lower_limit = func(new_lower_limit);
new_upper_limit = func(new_upper_limit);
if new_lower_limit > new_upper_limit {
Expand Down Expand Up @@ -548,6 +548,19 @@ fn adjust_limits(
}
}

// safety check: the limits may not be infinite.
// This could happen if the compu method multiplies an f64 datatype limit with any number > 1
if new_lower_limit == -f64::INFINITY {
new_lower_limit = f64::MIN;
} else if new_lower_limit == f64::INFINITY {
new_lower_limit = f64::MAX;
}
if new_upper_limit == -f64::INFINITY {
new_upper_limit = f64::MIN;
} else if new_upper_limit == f64::INFINITY {
new_upper_limit = f64::MAX;
}

(new_lower_limit, new_upper_limit)
}

Expand Down Expand Up @@ -685,6 +698,28 @@ mod test {
let (lower, upper) = adjust_limits(&typeinfo, 0.0, 0.0, Some(&compu_method));
assert_eq!(lower, 0.0);
assert_eq!(upper, 10200.0);

// for some RAT_FUNC compu method parameters, the limit calculation can go to infinity.
// Even the calculation order is a concern here, since multiplication before division
// could cause this even if the end result should be smaller than f64::MAX
let typeinfo = TypeInfo {
name: None,
unit_idx: 0,
datatype: DwarfDataType::Double,
dbginfo_offset: 0,
};
let mut compu_method = CompuMethod::new(
"name".to_string(),
"".to_string(),
ConversionType::RatFunc,
"".to_string(),
"".to_string(),
);
compu_method.coeffs = Some(Coeffs::new(0., 4.0, 0., 0., 0., 2.0));

let (lower, upper) = adjust_limits(&typeinfo, f64::MIN, f64::MAX, Some(&compu_method));
assert_ne!(lower, f64::MIN);
assert_ne!(upper, f64::MAX);
}

fn test_setup(a2l_name: &str) -> (crate::dwarf::DebugData, a2lfile::A2lFile) {
Expand Down

0 comments on commit 3cc9e35

Please sign in to comment.