File size: 3,870 Bytes
e996a55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "unity/unity.h"
#include "zlib.h"
#include <string.h>
#include <stdlib.h>

/* Wrapper provided in deflate.c for testing local function */
extern int test_deflateStateCheck(z_streamp strm);

void setUp(void) {
    /* no setup needed */
}

void tearDown(void) {
    /* no teardown needed */
}

static void init_stream(z_stream *strm) {
    memset(strm, 0, sizeof(*strm));
    int ret = deflateInit(strm, Z_DEFAULT_COMPRESSION);
    TEST_ASSERT_EQUAL_INT(Z_OK, ret);
}

void test_deflateStateCheck_NULL_stream_returns_1(void) {
    int rc = test_deflateStateCheck(NULL);
    TEST_ASSERT_EQUAL_INT(1, rc);
}

void test_deflateStateCheck_uninitialized_stream_returns_1(void) {
    z_stream s;
    memset(&s, 0, sizeof(s));
    /* zalloc and zfree are NULL; state is NULL */
    int rc = test_deflateStateCheck(&s);
    TEST_ASSERT_EQUAL_INT(1, rc);
}

void test_deflateStateCheck_after_deflateInit_is_valid(void) {
    z_stream strm;
    init_stream(&strm);

    int rc = test_deflateStateCheck(&strm);
    TEST_ASSERT_EQUAL_INT(0, rc);

    TEST_ASSERT_EQUAL_INT(Z_OK, deflateEnd(&strm));
}

void test_deflateStateCheck_in_BUSY_STATE_after_header_is_valid(void) {
    z_stream strm;
    init_stream(&strm);

    unsigned char out[128];
    strm.next_out = out;
    strm.avail_out = (uInt)sizeof(out);
    /* No input needed to emit zlib header and enter BUSY_STATE */
    int ret = deflate(&strm, Z_NO_FLUSH);
    TEST_ASSERT(ret == Z_OK || ret == Z_BUF_ERROR /* overly small out buf case */);

    int rc = test_deflateStateCheck(&strm);
    TEST_ASSERT_EQUAL_INT(0, rc);

    TEST_ASSERT_EQUAL_INT(Z_OK, deflateEnd(&strm));
}

void test_deflateStateCheck_in_FINISH_STATE_is_valid(void) {
    z_stream strm;
    init_stream(&strm);

    const unsigned char in[] = "Hello, zlib!";
    unsigned char out[1024];

    strm.next_in = (Bytef *)in;
    strm.avail_in = (uInt)sizeof(in) - 1; /* exclude terminating NUL */
    strm.next_out = out;
    strm.avail_out = (uInt)sizeof(out);

    int ret;
    do {
        ret = deflate(&strm, Z_FINISH);
        /* keep calling until stream end */
    } while (ret == Z_OK);
    TEST_ASSERT_EQUAL_INT(Z_STREAM_END, ret);

    int rc = test_deflateStateCheck(&strm);
    TEST_ASSERT_EQUAL_INT(0, rc);

    TEST_ASSERT_EQUAL_INT(Z_OK, deflateEnd(&strm));
}

void test_deflateStateCheck_with_state_from_different_stream_returns_1(void) {
    z_stream owner;
    init_stream(&owner);

    /* Build a second z_stream that points to the first stream's state. */
    z_stream imposter;
    memset(&imposter, 0, sizeof(imposter));
    /* Satisfy allocator checks so we get past the first condition */
    imposter.zalloc = owner.zalloc;
    imposter.zfree = owner.zfree;
    imposter.opaque = owner.opaque;
    /* Illegally point at someone else's state */
    imposter.state = owner.state;

    int rc = test_deflateStateCheck(&imposter);
    TEST_ASSERT_EQUAL_INT(1, rc);

    /* Clean up only the legitimate owner */
    TEST_ASSERT_EQUAL_INT(Z_OK, deflateEnd(&owner));
}

void test_deflateStateCheck_after_deflateEnd_returns_1(void) {
    z_stream strm;
    init_stream(&strm);

    TEST_ASSERT_EQUAL_INT(Z_OK, deflateEnd(&strm));

    /* zalloc/zfree are still set, but state is NULL -> should be invalid */
    int rc = test_deflateStateCheck(&strm);
    TEST_ASSERT_EQUAL_INT(1, rc);
}

int main(void) {
    UNITY_BEGIN();

    RUN_TEST(test_deflateStateCheck_NULL_stream_returns_1);
    RUN_TEST(test_deflateStateCheck_uninitialized_stream_returns_1);
    RUN_TEST(test_deflateStateCheck_after_deflateInit_is_valid);
    RUN_TEST(test_deflateStateCheck_in_BUSY_STATE_after_header_is_valid);
    RUN_TEST(test_deflateStateCheck_in_FINISH_STATE_is_valid);
    RUN_TEST(test_deflateStateCheck_with_state_from_different_stream_returns_1);
    RUN_TEST(test_deflateStateCheck_after_deflateEnd_returns_1);

    return UNITY_END();
}