ThrowTheSwitch / Unity

Simple Unit Testing for C
ThrowTheSwitch.org
MIT License
4.02k stars 969 forks source link

Bug: Boolean is found to be both true and false simultaneously #708

Closed jensenr30 closed 9 months ago

jensenr30 commented 10 months ago

if I memset(boolean, 90, sizeof(boolean)), it will cause Unity's assertions to behave unexpectedly. I created an example project that demonstrates this bug here:

https://github.com/jensenr30/unity/tree/boolean-bug/examples/boolean_bug

In that project, this is the test that passes which should fail:

/* This test demonstrates a bug where a boolean is considered both true and false simultaneously */
void test_boolean_memset_90_will_pass(void) {
    bool boolean;
    memset(&boolean, 90, sizeof(boolean));
    /* this test passes, as expected. */
    TEST_ASSERT_TRUE(boolean);
    /* this test also passes unexpectedly! */
    TEST_ASSERT_FALSE(boolean);
    /* how can both TEST_ASSERT_TRUE and TEST_ASSERT_FALSE both pass on the same boolean? */
}

This bug is made visible by my abuse of the boolean type - I'm setting it to a value other than 0 or 1. Still, I don't think it should be possible for unity to think a boolean is both true and false.

jensenr30 commented 10 months ago

Perhaps this bug could be fixed by defining TEST_ASSERT_TRUE in terms of TEST_ASSERT_FALSE so there can never be a discrepancy between the two? Or have them both use a common method of determining if a boolean is true or false.

E.g.

#define is_false(b) (b == 0)
#define TEST_ASSERT_FALSE(b) assert(is_false(b))
#define TEST_ASSERT_TRUE(b) assert(!is_false(b))
jensenr30 commented 10 months ago

It looks like this is not a bug with Unity per se.

I tried running this code in the same project:

    // ...
    bool boolean;
    memset(&boolean, 90, sizeof(boolean));
    if (boolean == true) {
        printf("boolean is true\n");
    }
    if (boolean == false) {
        printf("boolean is false\n");
    }
    if (boolean == 1) {
        printf("boolean is 1\n");
    }
    if (boolean == 0) {
        printf("boolean is 0\n");
    }
    // ...

And the output is:

boolean is true
boolean is false
boolean is 1
boolean is 0
mvandervoord commented 10 months ago

I can't reproduce the problem. Also, I suspect you're using an older Unity? The latest version has the following:

#define TEST_ASSERT_TRUE(condition)     UNITY_TEST_ASSERT(       (condition), __LINE__, " Expected TRUE Was FALSE")
#define TEST_ASSERT_FALSE(condition)    UNITY_TEST_ASSERT(      !(condition), __LINE__, " Expected FALSE Was TRUE")

As long as your compiler is working, I don't believe this could demonstrate the problem you're seeing.