mat007 / turtle

C++ mock object library for Boost

Home Page:http://turtle.sourceforge.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.