Skip to content

Null deferences when mocking unsigned char pointers #133

@johannes-bleisteiner-abrantix

Description

This is essentially the same issue as #115

The following testcase, where nullptr is passed as argument to the mocked function, causes an access violation if the expectation is not met, in default human-readable output format. For --log-format=JUNIT, and other detailed log level configurations, it causes an access violation even for an fully successful test.

MOCK_FUNCTION(Foo, 2, void(unsigned char *, size_t));

BOOST_AUTO_TEST_CASE(NullptrMockTest)
{
	MOCK_EXPECT(Foo).never();

	Foo(nullptr, 0);
}
Running 1 test case...
unknown location(0):
	error:
	in "NullptrMockTest":
	unexpected call:
	Foo( 
unknown location(0):
	fatal error:
	in "NullptrMockTest":
	memory access violation`

My usecase are cryptography-adjacent functions that are handling multiple input and output fields, passed in C-style pairs of unsigned char pointer (favored over void* for not needing to cast before array access) and length. In some situations certain optional data fields are not available and thus the function is passed a nullptr+0.

Pull request to follow; I plan to simply extend the Pull request 116 for unsigned char pointers (both mutable and const).

As a secondary issue; even in non-nullptr situations there is not a guarantee that the data pointer points to is NUL-terminated. Depending on luck, there might be a 0x00 somewhere in the data, or there might be a memory overread.

MOCK_FUNCTION(Foo, 2, void(unsigned char *, size_t));

BOOST_AUTO_TEST_CASE(UcharMockTest)
{
	unsigned char test[4] = {0x01, 0x64, 0x08, 0x65};
	MOCK_EXPECT(Foo).never();

	Foo(test, 4);
}
Running 1 test case...
unknown location(0):
	error:
	in "UcharMockTest":
	unexpected call:
	Foo( �d�eÌÌÌÌüÔ��Üä��]k,�ÿÿÿÿèä��Ž�›, 4 )
v never().with( any, any )

The same theoretically happens for signed char pointers (as in issue 115). But I appreciate that for the vast majority of users who aren't me, those will actually be C-style strings and outputting as a string is too useful. So this depends on use case, and the conventions of the codebase that is being tested/mocked.
https://turtle.sourceforge.net/turtle/customization.html suggests the ability to inject a custom serialization operator. This did work quite straightforward and easy for custom types, but no combination of namespace, const qualifiers, and order of includes I could think of convinced the compiler to use it for a native type like const unsigned char*. I only managed that by editing it directly into the turtle/stream.hpp, but my experience with template resolution behaviour is limited, so I'd be happy to hear it's possible after all. I do not have a good suggested solution for this dilemma otherwise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions