Skip to content

Commit 9370791

Browse files
GTEST/UCP: Add coverage of the lane address token sections
The token sections are parsed ahead of the packed addresses, so a malformed section must be rejected rather than shift the addresses. Feed crafted sections to the parser, including truncated ones, which the empty sections of the wire itself do not exercise.
1 parent 650200d commit 9370791

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

test/gtest/ucp/test_ucp_wireup.cc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,3 +2459,78 @@ UCS_TEST_P(test_ucp_reconfig_connect_remote, put_canceled)
24592459
}
24602460

24612461
UCP_INSTANTIATE_TEST_CASE_TLS(test_ucp_reconfig_connect_remote, tcp, "tcp")
2462+
2463+
2464+
/* The token sections of a LANES_ADDR message are parsed before the addresses,
2465+
* so a malformed section must be rejected rather than shift the addresses. */
2466+
class test_ucp_wireup_token_section : public ucs::test {
2467+
protected:
2468+
/* One length byte per lane, followed by the tokens themselves */
2469+
static std::vector<uint8_t> make_section(const std::vector<uint8_t> &lengths)
2470+
{
2471+
std::vector<uint8_t> section(lengths);
2472+
uint8_t value = 0;
2473+
2474+
for (std::vector<uint8_t>::const_iterator it = lengths.begin();
2475+
it != lengths.end(); ++it) {
2476+
section.insert(section.end(), *it, ++value);
2477+
}
2478+
2479+
return section;
2480+
}
2481+
2482+
static const ucp_lane_map_t THREE_LANES;
2483+
};
2484+
2485+
const ucp_lane_map_t test_ucp_wireup_token_section::THREE_LANES =
2486+
UCS_BIT(0) | UCS_BIT(3) | UCS_BIT(5);
2487+
2488+
UCS_TEST_F(test_ucp_wireup_token_section, unpack) {
2489+
std::vector<uint8_t> lengths = {4, 0, 7};
2490+
std::vector<uint8_t> section = make_section(lengths);
2491+
const uint8_t *unpacked_lengths;
2492+
const void *tokens;
2493+
size_t consumed;
2494+
2495+
/* The address follows the section, so extra bytes must be left alone */
2496+
section.push_back(0xff);
2497+
2498+
ASSERT_UCS_OK(ucp_wireup_unpack_token_section(THREE_LANES, &section[0],
2499+
section.size(), &consumed,
2500+
&unpacked_lengths, &tokens));
2501+
EXPECT_EQ(section.size() - 1, consumed);
2502+
EXPECT_EQ(lengths[0], unpacked_lengths[0]);
2503+
EXPECT_EQ(lengths[1], unpacked_lengths[1]);
2504+
EXPECT_EQ(lengths[2], unpacked_lengths[2]);
2505+
EXPECT_EQ(static_cast<const void*>(&section[lengths.size()]), tokens);
2506+
}
2507+
2508+
UCS_TEST_F(test_ucp_wireup_token_section, unpack_no_lanes) {
2509+
std::vector<uint8_t> section(4, 0);
2510+
const uint8_t *lengths;
2511+
const void *tokens;
2512+
size_t consumed;
2513+
2514+
ASSERT_UCS_OK(ucp_wireup_unpack_token_section(0, &section[0],
2515+
section.size(), &consumed,
2516+
&lengths, &tokens));
2517+
EXPECT_EQ(0ul, consumed);
2518+
EXPECT_EQ(NULL, lengths);
2519+
EXPECT_EQ(NULL, tokens);
2520+
}
2521+
2522+
UCS_TEST_F(test_ucp_wireup_token_section, unpack_truncated) {
2523+
std::vector<uint8_t> section = make_section({4, 0, 7});
2524+
const uint8_t *lengths;
2525+
const void *tokens;
2526+
size_t consumed;
2527+
2528+
/* Cut in the length array, and then in the tokens themselves */
2529+
EXPECT_EQ(UCS_ERR_MESSAGE_TRUNCATED,
2530+
ucp_wireup_unpack_token_section(THREE_LANES, &section[0], 2,
2531+
&consumed, &lengths, &tokens));
2532+
EXPECT_EQ(UCS_ERR_MESSAGE_TRUNCATED,
2533+
ucp_wireup_unpack_token_section(THREE_LANES, &section[0],
2534+
section.size() - 1, &consumed,
2535+
&lengths, &tokens));
2536+
}

0 commit comments

Comments
 (0)