@@ -2459,3 +2459,78 @@ UCS_TEST_P(test_ucp_reconfig_connect_remote, put_canceled)
24592459}
24602460
24612461UCP_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 , §ion[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 *>(§ion[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 , §ion[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 , §ion[0 ], 2 ,
2531+ &consumed, &lengths, &tokens));
2532+ EXPECT_EQ (UCS_ERR_MESSAGE_TRUNCATED ,
2533+ ucp_wireup_unpack_token_section (THREE_LANES , §ion[0 ],
2534+ section.size () - 1 , &consumed,
2535+ &lengths, &tokens));
2536+ }
0 commit comments