CodeQL 文档

不必要的防御性代码

ID: js/unneeded-defensive-code
Kind: problem
Security severity: 
Severity: recommendation
Precision: very-high
Tags:
   - correctness
   - external/cwe/cwe-570
   - external/cwe/cwe-571
Query suites:
   - javascript-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

防御性代码可以防止意外情况导致程序出现致命错误。常见的防御性代码模式是防止对 nullundefined 值进行解引用。但是,如果防御性代码所防止的情况永远不会发生,那么防御性代码就毫无用处,可以安全地将其删除。

建议

检查周围的代码,以确定防御性代码是否值得保留,即使它没有实际用途。如果不再需要它,请将其删除。

示例

以下示例显示了一个 cleanupLater 函数,该函数将在延迟一段时间后异步执行清理任务。当清理任务完成后,该函数将调用提供的回调参数 cb。为了防止在 cb 的值为 undefined 时调用 cb 导致崩溃,防御性代码通过检查 cb 是否为真来保护调用。

function cleanupLater(delay, cb) {
    setTimeout(function() {
        cleanup();
        if (cb) { // BAD: useless check, `cb` is always truthy
            cb();
        }
    }, delay)
}

cleanupLater(1000, function(){console.log("Cleanup done")});

但是,cleanupLater 函数总是使用回调参数调用,因此防御性代码条件总是成立,因此不需要它。因此,该函数可以简化为

function cleanupLater(delay, cb) {
    setTimeout(function() {
        cleanupNow();
        // GOOD: no need to guard the invocation
        cb();
    }, delay)
}

cleanupLater(function(){console.log("Cleanup done")});

多次防止相同情况是另一个例子,说明防御性代码没有实际用途。以下示例显示了一个将值赋给对象属性的函数,其中防御性代码确保赋予的值不是 undefinednull

function setSafeStringProp(o, prop, v) {
    // BAD: `v == null` is useless
    var safe = v == undefined || v == null? '': v;
    o[prop] = safe;
}

但是,由于强制转换规则,v == undefined 既适用于 vundefined 的情况,也适用于 vnull 的情况,因此 v == null 保护没有任何作用,可以将其删除

function setSafeStringProp(o, prop, v) {
    // GOOD: `v == undefined` handles both `undefined` and `null`
    var safe = v == undefined? '': v;
    o[prop] = safe;
}

参考文献

  • ©GitHub, Inc.
  • 条款
  • 隐私