CodeQL 文档

切片

ID: cpp/slicing
Kind: problem
Security severity: 
Severity: warning
Precision: high
Tags:
   - reliability
   - correctness
   - types
Query suites:
   - cpp-security-and-quality.qls

单击查看 CodeQL 仓库中的查询

此查询查找将派生类型的非引用实例分配给基类型变量的情况,其中派生类型比基类型具有更多字段。这些赋值会切除派生类型添加的所有字段,并在访问为派生类型时导致意外状态。

建议

将赋值左侧变量的类型更改为子类。

示例

static int idctr = 0;
//Basic connection with id
class Connection {
public:
    int connId;
    virtual void print_info() {
        cout << "id: " << connId << "\n";
    }
    Connection() {
        connId = idctr++;
    }
};

//Adds counters, and an overriding print_info
class MeteredConnection : public Connection {
public:
    int txCtr;
    int rxCtr;
    MeteredConnection() {
        txCtr = 0;
        rxCtr = 0;
    }
    virtual void print_info() {
        cout << "id: " << connId << "\n" << "tx/rx: " << txCtr << "/" << rxCtr << "\n";
    }
};

int main(int argc, char* argv[]) {
    Connection conn;
    MeteredConnection m_conn;

    Connection curr_conn = conn;
    curr_conn.print_info();
    curr_conn = m_conn; //Wrong: Derived MetricConnection assigned to Connection 
                        //variable, will slice off the counters and the overriding print_info
    curr_conn.print_info(); //Will not print the counters.

    Connection* curr_pconn = &conn;
    curr_pconn->print_info();
    curr_pconn = &m_conn; //Correct: Pointer assigned to address of the MetricConnection. 
                          //Counters and virtual functions remain intact.
    curr_pconn->print_info(); //Will call the correct method MeteredConnection::print_info
}

参考资料

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