Null dereferences when mocking C-style string arguments
AlexSmithEtas opened this issue · comments
Mocking methods / functions that take C-style string (i.e. char*
) arguments can lead to null dereferences, in some cases where nullptr
is expected and / or actually passed.
When a mock method / function is configured to expect a call with a non-null string, a nullptr
dereference occurs in the case that the code under test incorrectly passes nullptr
. Compare and contrast the behaviour of the following:
MOCK_FUNCTION( f, 1, void( const char* ) );
BOOST_FIXTURE_TEST_CASE( expect_non_null_get_non_null, mock::cleanup )
{
mock::sequence s;
MOCK_EXPECT( f ).once().in( s ).with( "correct" );
f( "wrong" );
mock::verify();
// We are correctly told that the `code under test' called f() with the
// string "wrong" when it should have passed "correct".
}
BOOST_FIXTURE_TEST_CASE( expect_non_null_get_null, mock::cleanup )
{
mock::sequence s;
MOCK_EXPECT( f ).once().in( s ).with( "test" );
f( nullptr );
mock::verify();
// Bang! nullptr is dereferenced.
}
When a mock method / function is configured to expect character pointer nullptr
to be passed to a C-style string argument, a nullptr
dereference occurs, regardless of whether the code under test passes nullptr
or a non-null string. Note that this does not occur when nullptr_t
nullptr
is expected, so is only a problem when e.g. a constant or definition that is more natural to the particular situation is used in the expectation, rather than explicitly expecting nullptr
. Compare and contrast the behaviour of the following:
// From some third-party API header:
typedef const char* some_api_string;
#define SOME_API_NO_STRING ( (const char*) NULL )
MOCK_FUNCTION( f, 1, void( some_api_string ) );
BOOST_FIXTURE_TEST_CASE( expect_nullptr_get_null, mock::cleanup )
{
mock::sequence s;
MOCK_EXPECT( f ).once().in( s ).with( nullptr );
f( SOME_API_NO_STRING );
mock::verify();
// We are correctly told that the test passed.
}
BOOST_FIXTURE_TEST_CASE( expect_null_get_null, mock::cleanup )
{
mock::sequence s;
MOCK_EXPECT( f ).once().in( s ).with( SOME_API_NO_STRING );
f( SOME_API_NO_STRING );
mock::verify();
// Bang! nullptr is dereferenced.
}
BOOST_FIXTURE_TEST_CASE( expect_null_get_non_null, mock::cleanup )
{
mock::sequence s;
MOCK_EXPECT( f ).once().in( s ).with( SOME_API_NO_STRING );
f( "wrong" );
mock::verify();
// Bang! nullptr is dereferenced.
}
These nullptr
dereferences occur because there are no runtime checks for the nullptr
cases in the matcher and serializer for C-style strings. Pull request to follow.