掩护 - 明确的无效解雇

Coverity -- Explicit null dereference

本文关键字:无效 掩护      更新时间:2023-10-16

我有这样的场景:

int main() {
  int *p;
  int *q;
  bool cond1, cond2;
  // Does some processing and sets the cond1 and cond2
  if (cond1) {
     p = // Assign valid address
     q = NULL;
  } else {
     p = NULL;
     q = // Assign valid address
  }
  // Does something else but cond1 and cond2 remains untouched  
  if (cond2) {
    ***// Using 'q' data members.***
  }
}

我的代码Cond1和Cond2中只有两个凝结。首先,如果执行cond1,否则执行cond2。我看到具有粗体/斜体代码的覆盖性缺陷。封面抱怨以下消息:

CID 25469 (#1 of 1): Explicit null dereferenced (FORWARD_NULL)
9. var_deref_op: Dereferencing null pointer q.

我不明白为什么保险公司在这里抱怨。在这种情况下,到当时,我进入了" cond2",我已经有" q"集。正确的?我不明白的是什么?

我提出的解决方案:

..如果我写!cond1会没关系:

if (!cond1) {
  // Using 'q' data members.
}

..如果我添加额外的支票:

可以
if (cond2 && q != NULL) {
  // Using 'q' data members.
}

..是假阳性吗?

还有什么吗?预先感谢您。

从逻辑上讲,基于您所说的话,并且假设code1code2是相互排斥的,这是一个假阳性。但是,警告具有值,因为它指向 [sic] q的安全性在您函数的逻辑上并不明显。

我至少会在if (code2)中放置一个assert(q),但是:

  1. 断言通常仅适用于调试时间(因为最近我想起了发行版的运行时崩溃,这毫无意义地;毕竟,我到处都有断言安全,对吗?(
  2. 这可能仍然不足以满足掩护。

理想情况下,您会坚持使用一个if/else,然后将所有逻辑放入其中。在中间执行的常见逻辑?将其分成可以调用的其他功能。

添加的好处是您可能不再需要pq,因此整个功能变得更加精简。

如果code1code2都可能是正确的,那么您确实有一个很大的错误。