• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ==========================================
2  *  Unity Project - A Test Framework for C
3  *  Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
4  *  [Released under MIT License. Please refer to license.txt for details]
5  * ========================================== */
6 
7 #include "unity.h"
8 #include "unity_memory.h"
9 #include "unity_output_Spy.h"
10 #include <stdlib.h>
11 #include <string.h>
12 
13 /* This test module includes the following tests: */
14 
15 void test_ForceMallocFail(void);
16 void test_ReallocSmallerIsUnchanged(void);
17 void test_ReallocSameIsUnchanged(void);
18 void test_ReallocLargerNeeded(void);
19 void test_ReallocNullPointerIsLikeMalloc(void);
20 void test_ReallocSizeZeroFreesMemAndReturnsNullPointer(void);
21 void test_CallocFillsWithZero(void);
22 void test_FreeNULLSafety(void);
23 void test_DetectsLeak(void);
24 void test_BufferOverrunFoundDuringFree(void);
25 void test_BufferOverrunFoundDuringRealloc(void);
26 void test_BufferGuardWriteFoundDuringFree(void);
27 void test_BufferGuardWriteFoundDuringRealloc(void);
28 void test_MallocPastBufferFails(void);
29 void test_CallocPastBufferFails(void);
30 void test_MallocThenReallocGrowsMemoryInPlace(void);
31 void test_ReallocFailDoesNotFreeMem(void);
32 
33 /* It makes use of the following features */
34 void setUp(void);
35 void tearDown(void);
36 
37 /* Let's Go! */
setUp(void)38 void setUp(void)
39 {
40 #ifdef UNITY_EXCLUDE_STDLIB_MALLOC
41     UnityOutputCharSpy_Create(200);
42 #else
43     UnityOutputCharSpy_Create(1000);
44 #endif
45     UnityMalloc_StartTest();
46 }
47 
tearDown(void)48 void tearDown(void)
49 {
50     UnityMalloc_EndTest();
51     UnityOutputCharSpy_Destroy();
52 }
53 
test_ForceMallocFail(void)54 void test_ForceMallocFail(void)
55 {
56     void* m;
57     void* mfails;
58     UnityMalloc_MakeMallocFailAfterCount(1);
59     m = malloc(10);
60     TEST_ASSERT_NOT_NULL(m);
61     mfails = malloc(10);
62     TEST_ASSERT_EQUAL_PTR(0, mfails);
63     free(m);
64 }
65 
test_ReallocSmallerIsUnchanged(void)66 void test_ReallocSmallerIsUnchanged(void)
67 {
68     void* m1 = malloc(10);
69     void* m2 = realloc(m1, 5);
70     TEST_ASSERT_NOT_NULL(m1);
71     TEST_ASSERT_EQUAL_PTR(m1, m2);
72     free(m2);
73 }
74 
test_ReallocSameIsUnchanged(void)75 void test_ReallocSameIsUnchanged(void)
76 {
77     void* m1 = malloc(10);
78     void* m2 = realloc(m1, 10);
79     TEST_ASSERT_NOT_NULL(m1);
80     TEST_ASSERT_EQUAL_PTR(m1, m2);
81     free(m2);
82 }
83 
test_ReallocLargerNeeded(void)84 void test_ReallocLargerNeeded(void)
85 {
86     void* m2;
87     void* m1 = malloc(10);
88     TEST_ASSERT_NOT_NULL(m1);
89     strcpy((char*)m1, "123456789");
90     m2 = realloc(m1, 15);
91     TEST_ASSERT_EQUAL_STRING("123456789", m2);
92     free(m2);
93 }
94 
test_ReallocNullPointerIsLikeMalloc(void)95 void test_ReallocNullPointerIsLikeMalloc(void)
96 {
97     void* m = realloc(0, 15);
98     TEST_ASSERT_NOT_NULL(m);
99     free(m);
100 }
101 
test_ReallocSizeZeroFreesMemAndReturnsNullPointer(void)102 void test_ReallocSizeZeroFreesMemAndReturnsNullPointer(void)
103 {
104     void* m1 = malloc(10);
105     void* m2 = realloc(m1, 0);
106     TEST_ASSERT_EQUAL_PTR(0, m2);
107 }
108 
test_CallocFillsWithZero(void)109 void test_CallocFillsWithZero(void)
110 {
111     void* m = calloc(3, sizeof(char));
112     char* s = (char*)m;
113     TEST_ASSERT_NOT_NULL(m);
114     TEST_ASSERT_EQUAL_HEX8(0, s[0]);
115     TEST_ASSERT_EQUAL_HEX8(0, s[1]);
116     TEST_ASSERT_EQUAL_HEX8(0, s[2]);
117     free(m);
118 }
119 
test_FreeNULLSafety(void)120 void test_FreeNULLSafety(void)
121 {
122     free(NULL);
123 }
124 
125 /*------------------------------------------------------------ */
126 
127 #define EXPECT_ABORT_BEGIN \
128   { \
129     jmp_buf TestAbortFrame;   \
130     memcpy(TestAbortFrame, Unity.AbortFrame, sizeof(jmp_buf)); \
131     if (TEST_PROTECT()) \
132     {
133 
134 #define EXPECT_ABORT_END \
135     } \
136     memcpy(Unity.AbortFrame, TestAbortFrame, sizeof(jmp_buf)); \
137   }
138 
139 /* This tricky set of defines lets us see if we are using the Spy, returns 1 if true */
140 #ifdef __STDC_VERSION__
141 
142 #ifdef UNITY_SUPPORT_VARIADIC_MACROS
143 #define USING_SPY_AS(a)                    EXPAND_AND_USE_2ND(ASSIGN_VALUE(a), 0)
144 #define ASSIGN_VALUE(a)                    VAL_##a
145 #define VAL_UnityOutputCharSpy_OutputChar  0, 1
146 #define EXPAND_AND_USE_2ND(a, b)           SECOND_PARAM(a, b, throwaway)
147 #define SECOND_PARAM(a, b, ...)            b
148 #if USING_SPY_AS(UNITY_OUTPUT_CHAR)
149   #define USING_OUTPUT_SPY /* UNITY_OUTPUT_CHAR = UnityOutputCharSpy_OutputChar */
150 #endif
151 #endif /* UNITY_SUPPORT_VARIADIC_MACROS */
152 
153 #else  /* __STDC_VERSION__ else */
154 
155 #define UnityOutputCharSpy_OutputChar 42
156 #if UNITY_OUTPUT_CHAR == UnityOutputCharSpy_OutputChar /* Works if no -Wundef -Werror */
157   #define USING_OUTPUT_SPY
158 #endif
159 #undef UnityOutputCharSpy_OutputChar
160 
161 #endif /* __STDC_VERSION__ */
162 
test_DetectsLeak(void)163 void test_DetectsLeak(void)
164 {
165 #ifdef USING_OUTPUT_SPY
166     void* m = malloc(10);
167     TEST_ASSERT_NOT_NULL(m);
168     UnityOutputCharSpy_Enable(1);
169     EXPECT_ABORT_BEGIN
170     UnityMalloc_EndTest();
171     EXPECT_ABORT_END
172     UnityOutputCharSpy_Enable(0);
173     Unity.CurrentTestFailed = 0;
174     TEST_ASSERT_NOT_NULL(strstr(UnityOutputCharSpy_Get(), "This test leaks!"));
175     free(m);
176 #else
177     TEST_IGNORE_MESSAGE("Enable USING_OUTPUT_SPY To Run This Test");
178 #endif
179 }
180 
test_BufferOverrunFoundDuringFree(void)181 void test_BufferOverrunFoundDuringFree(void)
182 {
183 #ifdef USING_OUTPUT_SPY
184     void* m = malloc(10);
185     char* s = (char*)m;
186     TEST_ASSERT_NOT_NULL(m);
187     s[10] = (char)0xFF;
188     UnityOutputCharSpy_Enable(1);
189     EXPECT_ABORT_BEGIN
190     free(m);
191     EXPECT_ABORT_END
192     UnityOutputCharSpy_Enable(0);
193     Unity.CurrentTestFailed = 0;
194     TEST_ASSERT_NOT_NULL(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()"));
195 #else
196     TEST_IGNORE_MESSAGE("Enable USING_OUTPUT_SPY To Run This Test");
197 #endif
198 }
199 
test_BufferOverrunFoundDuringRealloc(void)200 void test_BufferOverrunFoundDuringRealloc(void)
201 {
202 #ifdef USING_OUTPUT_SPY
203     void* m = malloc(10);
204     char* s = (char*)m;
205     TEST_ASSERT_NOT_NULL(m);
206     s[10] = (char)0xFF;
207     UnityOutputCharSpy_Enable(1);
208     EXPECT_ABORT_BEGIN
209     m = realloc(m, 100);
210     EXPECT_ABORT_END
211     UnityOutputCharSpy_Enable(0);
212     Unity.CurrentTestFailed = 0;
213     TEST_ASSERT_NOT_NULL(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()"));
214 #else
215     TEST_IGNORE_MESSAGE("Enable USING_OUTPUT_SPY To Run This Test");
216 #endif
217 }
218 
test_BufferGuardWriteFoundDuringFree(void)219 void test_BufferGuardWriteFoundDuringFree(void)
220 {
221 #ifdef USING_OUTPUT_SPY
222     void* m = malloc(10);
223     char* s = (char*)m;
224     TEST_ASSERT_NOT_NULL(m);
225     s[-1] = (char)0x00; /* Will not detect 0 */
226     s[-2] = (char)0x01;
227     UnityOutputCharSpy_Enable(1);
228     EXPECT_ABORT_BEGIN
229     free(m);
230     EXPECT_ABORT_END
231     UnityOutputCharSpy_Enable(0);
232     Unity.CurrentTestFailed = 0;
233     TEST_ASSERT_NOT_NULL(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()"));
234 #else
235     TEST_IGNORE_MESSAGE("Enable USING_OUTPUT_SPY To Run This Test");
236 #endif
237 }
238 
test_BufferGuardWriteFoundDuringRealloc(void)239 void test_BufferGuardWriteFoundDuringRealloc(void)
240 {
241 #ifdef USING_OUTPUT_SPY
242     void* m = malloc(10);
243     char* s = (char*)m;
244     TEST_ASSERT_NOT_NULL(m);
245     s[-1] = (char)0x0A;
246     UnityOutputCharSpy_Enable(1);
247     EXPECT_ABORT_BEGIN
248     m = realloc(m, 100);
249     EXPECT_ABORT_END
250     UnityOutputCharSpy_Enable(0);
251     Unity.CurrentTestFailed = 0;
252     TEST_ASSERT_NOT_NULL(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()"));
253 #else
254     TEST_IGNORE_MESSAGE("Enable USING_OUTPUT_SPY To Run This Test");
255 #endif
256 }
257 
258 /*------------------------------------------------------------ */
259 
260 #define TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(first_mem_ptr, ptr) \
261     ptr = malloc(10); free(ptr);                                   \
262     TEST_ASSERT_EQUAL_PTR_MESSAGE(first_mem_ptr, ptr, "Memory was stranded, free in LIFO order");
263 
test_MallocPastBufferFails(void)264 void test_MallocPastBufferFails(void)
265 {
266 #ifdef UNITY_EXCLUDE_STDLIB_MALLOC
267     void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
268     void* n = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
269     free(m);
270     TEST_ASSERT_NOT_NULL(m);
271     TEST_ASSERT_NULL(n);
272     TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
273 #else
274     TEST_IGNORE_MESSAGE("Enable UNITY_EXCLUDE_STDLIB_MALLOC to Run This Test");
275 #endif
276 }
277 
test_CallocPastBufferFails(void)278 void test_CallocPastBufferFails(void)
279 {
280 #ifdef UNITY_EXCLUDE_STDLIB_MALLOC
281     void* m = calloc(1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
282     void* n = calloc(1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
283     free(m);
284     TEST_ASSERT_NOT_NULL(m);
285     TEST_ASSERT_NULL(n);
286     TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
287 #else
288     TEST_IGNORE_MESSAGE("Enable UNITY_EXCLUDE_STDLIB_MALLOC to Run This Test");
289 #endif
290 }
291 
test_MallocThenReallocGrowsMemoryInPlace(void)292 void test_MallocThenReallocGrowsMemoryInPlace(void)
293 {
294 #ifdef UNITY_EXCLUDE_STDLIB_MALLOC
295     void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
296     void* n = realloc(m, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 9);
297     free(n);
298     TEST_ASSERT_NOT_NULL(m);
299     TEST_ASSERT_EQUAL(m, n);
300     TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
301 #else
302     TEST_IGNORE_MESSAGE("Enable UNITY_EXCLUDE_STDLIB_MALLOC to Run This Test");
303 #endif
304 }
305 
test_ReallocFailDoesNotFreeMem(void)306 void test_ReallocFailDoesNotFreeMem(void)
307 {
308 #ifdef UNITY_EXCLUDE_STDLIB_MALLOC
309     void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
310     void* n1 = malloc(10);
311     void* out_of_mem = realloc(n1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
312     void* n2 = malloc(10);
313 
314     free(n2);
315     if (out_of_mem == NULL) free(n1);
316     free(m);
317 
318     TEST_ASSERT_NOT_NULL(m);       /* Got a real memory location */
319     TEST_ASSERT_NULL(out_of_mem);  /* The realloc should have failed */
320     TEST_ASSERT_NOT_EQUAL(n2, n1); /* If n1 != n2 then realloc did not free n1 */
321     TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n2);
322 #else
323     TEST_IGNORE_MESSAGE("Enable UNITY_EXCLUDE_STDLIB_MALLOC to Run This Test");
324 #endif
325 }
326