diff a/libs/performance/analysis/pyrograph/src/parse/js/expressions.rs b/libs/performance/analysis/pyrograph/src/parse/js/expressions.rs (rejected hunks)
@@ -24,6 +24,31 @@ fn network_tainted_param_indices(call_name: &str) -> Vec<usize> {
}
impl JsParser {
+
+ pub(super) fn try_infer_numeric_literal(&self, expr: &Expr) -> Option<f64> {
+ match expr {
+ Expr::Lit(Lit::Num(n)) => Some(n.value),
+ Expr::Bin(b) => {
+ let l = self.try_infer_numeric_literal(&b.left)?;
+ let r = self.try_infer_numeric_literal(&b.right)?;
+ match b.op {
+ BinaryOp::Add => Some(l + r),
+ BinaryOp::Sub => Some(l - r),
+ BinaryOp::Mul => Some(l * r),
+ BinaryOp::Div => if r != 0.0 { Some(l / r) } else { None },
+ BinaryOp::BitOr => Some(((l as i64) | (r as i64)) as f64),
+ BinaryOp::BitAnd => Some(((l as i64) & (r as i64)) as f64),
+ BinaryOp::BitXor => Some(((l as i64) ^ (r as i64)) as f64),
+ BinaryOp::LShift => Some(((l as i64) << (r as i64)) as f64),
+ BinaryOp::RShift => Some(((l as i64) >> (r as i64)) as f64),
+ _ => None,
+ }
+ }
+ Expr::Paren(p) => self.try_infer_numeric_literal(&p.expr),
+ _ => None,
+ }
+ }
+
pub(super) fn try_infer_string_literal(&self, expr: &Expr) -> Option<String> {
match expr {
Expr::Lit(Lit::Str(s)) => Some(s.value.to_string()),
@@ -41,7 +66,7 @@ impl JsParser {
for (i, q) in t.quasis.iter().enumerate() {
s.push_str(q.raw.as_ref());
if let Some(expr) = t.exprs.get(i) {
- s.push_str(&self.try_infer_string_literal(&expr.expr)?);
+ s.push_str(&self.try_infer_string_literal(&expr)?);
}
}
Some(s)
@@ -58,8 +83,8 @@ impl JsParser {
if prop.sym == "fromCharCode" {
let mut s = String::new();
for arg in &c.args {
- if let Expr::Lit(Lit::Num(n)) = &*arg.expr {
- if let Some(ch) = std::char::from_u32(n.value as u32) {
+ if let Some(n) = self.try_infer_numeric_literal(&arg.expr) {
+ if let Some(ch) = std::char::from_u32(n as u32) {
s.push(ch);
} else {
return None;