From 28f1d6493bf46df69a8e71d41659755804f3919e Mon Sep 17 00:00:00 2001 From: sabith saheb Date: Fri, 2 Oct 2026 02:53:31 +0530 Subject: [PATCH] bound cf_table reads when building the cfg and call graph --- centipede/call_graph.cc | 6 +++--- centipede/call_graph_test.cc | 9 +++++++++ centipede/control_flow.cc | 6 +++--- centipede/control_flow_test.cc | 9 +++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/centipede/call_graph.cc b/centipede/call_graph.cc index b78c37f9d..5179d245c 100644 --- a/centipede/call_graph.cc +++ b/centipede/call_graph.cc @@ -43,18 +43,18 @@ void CallGraph::InitializeCallGraph(const CFTable &cf_table, if (IsFunctionEntry(current_pc)) current_function_entry = current_pc; // Iterate over successors. - while (cf_table[j]) { + while (j < cf_table.size() && cf_table[j]) { ++j; } ++j; // Step over the delimeter. // Iterate over callees. - while (cf_table[j]) { + while (j < cf_table.size() && cf_table[j]) { current_callees.push_back(cf_table[j]); ++j; } ++j; // Step over the delimeter. - FUZZTEST_CHECK_LE(j, cf_table.size()); + FUZZTEST_CHECK_LE(j, cf_table.size()) << "Malformed CF table"; if (current_callees.empty()) continue; basic_block_callees_[current_pc] = current_callees; diff --git a/centipede/call_graph_test.cc b/centipede/call_graph_test.cc index 3bc2a51a7..35f4cd8a2 100644 --- a/centipede/call_graph_test.cc +++ b/centipede/call_graph_test.cc @@ -72,6 +72,15 @@ TEST(CallGraphDeathTest, CgNoneExistentPc) { EXPECT_DEATH(call_graph.GetBasicBlockCallees(666), ""); } +TEST(CallGraphDeathTest, CgTruncatedCfTable) { + // The record for PC 1 is missing both of its delimiters, which is what a + // partially written cf-table file looks like. + static const CFTable truncated_cf_table = {1, 2, 3}; + CallGraph call_graph; + EXPECT_DEATH(call_graph.InitializeCallGraph(truncated_cf_table, g_pc_table), + "Malformed CF table"); +} + TEST(CallGraph, BuildCgFromCfTable) { CallGraph call_graph; call_graph.InitializeCallGraph(g_cf_table, g_pc_table); diff --git a/centipede/control_flow.cc b/centipede/control_flow.cc index 2b0f2069f..465e97dc7 100644 --- a/centipede/control_flow.cc +++ b/centipede/control_flow.cc @@ -145,7 +145,7 @@ void ControlFlowGraph::InitializeControlFlowGraph(const CFTable &cf_table, ++j; // Iterate over successors. - while (cf_table[j]) { + while (j < cf_table.size() && cf_table[j]) { successors.push_back(cf_table[j]); ++j; } @@ -157,11 +157,11 @@ void ControlFlowGraph::InitializeControlFlowGraph(const CFTable &cf_table, FUZZTEST_VLOG(100) << "Added PC: " << curr_pc; // Iterate over callees. - while (cf_table[j]) { + while (j < cf_table.size() && cf_table[j]) { ++j; } ++j; // Step over the delimiter. - FUZZTEST_CHECK_LE(j, cf_table.size()); + FUZZTEST_CHECK_LE(j, cf_table.size()) << "Malformed CF table"; } // Calculate cyclomatic complexity for all functions. for (PCIndex i = 0; i < pc_table.size(); ++i) { diff --git a/centipede/control_flow_test.cc b/centipede/control_flow_test.cc index 0c687c732..2ebc0d9c2 100644 --- a/centipede/control_flow_test.cc +++ b/centipede/control_flow_test.cc @@ -98,6 +98,15 @@ TEST(CFTable, MakeCfgFromCfTable) { FUZZTEST_CHECK_EQ(cfg.GetCyclomaticComplexity(1), 2); } +TEST(CFTableDeathTest, MakeCfgFromTruncatedCfTable) { + // The record for PC 1 is missing both of its delimiters, which is what a + // partially written cf-table file looks like. + static const CFTable truncated_cf_table = {1, 2, 3}; + ControlFlowGraph cfg; + EXPECT_DEATH(cfg.InitializeControlFlowGraph(truncated_cf_table, g_pc_table), + "Malformed CF table"); +} + TEST(CFTable, SerializesAndDeserializesCfTable) { std::stringstream stream; WriteCfTable(g_cf_table, stream);