Throw overflow_exception instead of silently cutting off data

This commit is contained in:
Peter Conrad 2018-08-19 18:51:45 +02:00
parent 1dcacbafc9
commit 79ff75423f
2 changed files with 11 additions and 15 deletions

View file

@ -172,9 +172,11 @@ namespace fc {
uint64_t v = 0; char b = 0; uint8_t by = 0;
do {
s.get(b);
if( by >= 64 || (by == 63 && b > 1) )
FC_THROW_EXCEPTION( overflow_exception, "Invalid packed unsigned_int!" );
v |= uint64_t(uint8_t(b) & 0x7f) << by;
by += 7;
} while( (uint8_t(b) & 0x80) && by < 64 );
} while( uint8_t(b) & 0x80 );
vi.value = static_cast<uint64_t>(v);
}

View file

@ -62,7 +62,7 @@ static const std::vector<fc::unsigned_int> TEST_U = {
0xffffffffffffffffULL // \377\377\377\377\377\377\377\377\377\1
};
BOOST_AUTO_TEST_CASE( test_unsigned )
{
{ try {
const std::vector<char> packed_u = fc::raw::pack<std::vector<fc::unsigned_int>>( TEST_U, 3 );
BOOST_CHECK_EQUAL( UINT_LENGTH, packed_u.size() );
BOOST_CHECK_EQUAL( EXPECTED_UINTS, std::string( packed_u.data(), packed_u.size() ) );
@ -83,22 +83,16 @@ BOOST_AUTO_TEST_CASE( test_unsigned )
BOOST_CHECK_EQUAL( TEST_U.size(), unjson_u.size() );
for( size_t i = 0; i < TEST_U.size(); i++ )
BOOST_CHECK_EQUAL( TEST_U[i].value, unjson_u[i].value );
}
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE( test_limits )
{ try {
static const std::string PACKED_U = "\04"
"\200\1"
"\200\200\200\200\200\200\200\200\100"
"\200\200\200\200\200\200\200\200\200\201" // not terminated
"\200\200\200\200\200\200\200\200\300\201"; // not terminated
std::vector<fc::unsigned_int> unpacked_u;
fc::raw::unpack( std::vector<char>( PACKED_U.begin(), PACKED_U.end() ), unpacked_u, 3 );
BOOST_REQUIRE_EQUAL( 4, unpacked_u.size() );
BOOST_CHECK_EQUAL( 0x80, unpacked_u[0].value );
BOOST_CHECK_EQUAL( 0x4000000000000000ULL, unpacked_u[1].value );
BOOST_CHECK_EQUAL( 0x8000000000000000ULL, unpacked_u[2].value );
BOOST_CHECK_EQUAL( 0xc000000000000000ULL, unpacked_u[3].value );
static const std::string overflow = "\200\200\200\200\200\200\200\200\200\2"; // = 2^64
static const std::string overlong = "\200\200\200\200\200\200\200\200\300\200\1";
fc::unsigned_int dest;
BOOST_CHECK_THROW( fc::raw::unpack( std::vector<char>( overflow.begin(), overflow.end() ), dest, 3 ), fc::overflow_exception );
BOOST_CHECK_THROW( fc::raw::unpack( std::vector<char>( overlong.begin(), overlong.end() ), dest, 3 ), fc::overflow_exception );
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_SUITE_END()