-
Notifications
You must be signed in to change notification settings - Fork 20
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.