blob: 84442f106884f25f13729f314d5c70d8c7a0b870 [file] [log] [blame]
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001/*==============================================================================
2Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28==============================================================================*/
29
30#include "UsefulBuf.h"
31#include <string.h>
32
33
34/* Basic exercise...
35
36 Call all the main public functions.
37
38 Binary compare the result to the expected.
39
40 There is nothing adversarial in this test
41 */
42const char * NonAdversarialUOBTest()
43{
44 const char *szReturn = NULL;
45
46 char outbuf[50];
47
48 UsefulOutBuf UOB;
49
50 UsefulOutBuf_Init(&UOB, outbuf, sizeof(outbuf));
51
52 if(!UsefulOutBuf_AtStart(&UOB)) {
53 szReturn = "Not at start";
54 goto Done;
55 }
56
57 // Put 7 bytes at beginning of buf
58 UsefulOutBuf_AppendData(&UOB, "bluster", 7);
59
60 if(UsefulOutBuf_AtStart(&UOB)) {
61 szReturn = "At start";
62 goto Done;
63 }
64
65 // add a space to end
66 UsefulOutBuf_AppendByte(&UOB, ' ');
67
68 // Add 5 bytes to the end
69 UsefulBufC UBC = {"hunny", 5};
70 UsefulOutBuf_AppendUsefulBuf(&UOB, UBC);
71
72 // Insert 9 bytes at the beginning, slide the previous stuff right
73 UsefulOutBuf_InsertData(&UOB, "heffalump", 9, 0);
74 UsefulOutBuf_InsertByte(&UOB, ' ', 9);
75
76 // Put 9 bytes in at position 10 -- just after "heffalump "
77 UsefulBufC UBC2 = {"unbounce ", 9};
78 UsefulOutBuf_InsertUsefulBuf(&UOB, UBC2, 10);
79
80 // Make it a null terminated string (because all the appends and inserts above not strcpy !)
81 UsefulOutBuf_AppendByte(&UOB, '\0');
82
83
84 UsefulBuf U;
85 int nErr = UsefulOutBuf_OutUBuf(&UOB, &U);
86
87 const char *expected = "heffalump unbounce bluster hunny";
88
89 if(nErr || U.len-1 != strlen(expected) || strcmp(expected, U.ptr) || UsefulOutBuf_GetError(&UOB)) {
90 szReturn = "OutUBuf";
91 }
92
93 char buf[50];
94 size_t xxx;
95 nErr = UsefulOutBuf_CopyOut(&UOB, buf, sizeof(buf), &xxx);
96
97 if(nErr || xxx-1 != strlen(expected) || strcmp(expected, buf)) {
98 szReturn = "CopyOut";
99 }
100
101Done:
102 return szReturn;
103}
104
105
106/*
107 Append test utility.
108 pUOB is the buffer to append too
109 num is the amount to append
110 expected is the expected return code, 0 or 1
111
112 returns 0 if test passed
113
114 */
115static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
116{
117 //reset
118 UsefulOutBuf_Reset(pUOB);
119
120 // check status first
121 if(UsefulOutBuf_GetError(pUOB))
122 return 1;
123
124 // append the bytes
125 UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
126
127 // check error status after
128 if(UsefulOutBuf_GetError(pUOB) != expected)
129 return 1;
130
131 return 0;
132}
133
134
135/*
136 Same as append, but takes a position param too
137 */
138static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected)
139{
140 //reset
141 UsefulOutBuf_Reset(pUOB);
142
143 // check
144 if(UsefulOutBuf_GetError(pUOB))
145 return 1;
146
147 UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
148
149 if(UsefulOutBuf_GetError(pUOB) != expected)
150 return 1;
151
152 return 0;
153}
154
155
156/*
157 Boundary conditions to test
158 - around 0
159 - around the buffer size
160 - around MAX size_t
161
162
163 Test these for the buffer size and the cursor, the insert amount, the append amount and the insert position
164
165 */
166
167const char *BoundaryConditionsTest()
168{
169 char outbuf[2];
170
171 UsefulOutBuf UOB;
172
173 UsefulOutBuf_Init(&UOB, outbuf, sizeof(outbuf));
174
175 // append 0 byte to a 2 byte buffer --> success
176 if(AppendTest(&UOB, 0, 0))
177 return "Append 0 bytes failed";
178
179 // append 1 byte to a 2 byte buffer --> success
180 if(AppendTest(&UOB, 1, 0))
181 return "Append of 1 byte failed";
182
183 // append 2 byte to a 2 byte buffer --> success
184 if(AppendTest(&UOB, 2, 0))
185 return "Append to fill buffer failed";
186
187 // append 3 bytes to a 2 byte buffer --> failure
188 if(AppendTest(&UOB, 3, 1))
189 return "Overflow of buffer not caught";
190
191 // append max size_t to a 2 byte buffer --> failure
192 if(AppendTest(&UOB, SIZE_MAX, 1))
193 return "Append of SIZE_MAX error not caught";
194
195 if(InsertTest(&UOB, 1, 0, 0))
196 return "Insert 1 byte at start failed";
197
198 if(InsertTest(&UOB, 2, 0, 0))
199 return "Insert 2 bytes at start failed";
200
201 if(InsertTest(&UOB, 3, 0, 1))
202 return "Insert overflow not caught";
203
204 if(InsertTest(&UOB, 1, 1, 1))
205 return "Bad insertion point not caught";
206
207
208 char outBuf2[10];
209
210 UsefulOutBuf_Init(&UOB, outBuf2, sizeof(outBuf2));
211
212 UsefulOutBuf_Reset(&UOB);
213 // put data in the buffer
214 UsefulOutBuf_AppendData(&UOB, "abc123", 6);
215
216 UsefulOutBuf_InsertData(&UOB, "xyz*&^", 6, 0);
217
218 if(!UsefulOutBuf_GetError(&UOB)) {
219 return "insert with data should have failed";
220 }
221
222
223 UsefulOutBuf_Init(&UOB, NULL, SIZE_MAX - 5);
224 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
225 if(UsefulOutBuf_GetError(&UOB)) {
226 return "insert in huge should have succeeded";
227 }
228
229 UsefulOutBuf_Init(&UOB, NULL, SIZE_MAX - 5);
230 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
231 if(UsefulOutBuf_GetError(&UOB)) {
232 return "insert in huge should have succeeded";
233 }
234
235 UsefulOutBuf_Init(&UOB, NULL, SIZE_MAX - 5);
236 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
237 if(!UsefulOutBuf_GetError(&UOB)) {
238 return "lengths near max size";
239 }
240
241 return NULL;
242
243}
244
245
246
247
248
249// Test function to get size and magic number check
250
251const char *TestBasicSanity()
252{
253 char outbuf[10];
254
255 UsefulOutBuf UOB;
256
257 // First -- make sure that the room left function returns the right amount
258 UsefulOutBuf_Init(&UOB, outbuf, sizeof(outbuf));
259
260 if(UsefulOutBuf_RoomLeft(&UOB) != sizeof(outbuf))
261 return "room left failed";
262
263
264 // Next -- make sure that the magic number checking is working right
265 UOB.magic = 8888; // make magic bogus
266
267 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
268
269 if(!UsefulOutBuf_GetError(&UOB))
270 return "magic corruption check failed";
271
272
273
274 // Next make sure that the valid data length check is working right
275 UsefulOutBuf_Init(&UOB, outbuf, sizeof(outbuf));
276
277 UOB.UB.len = UOB.size+1; // make size bogus
278
279 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
280 if(!UsefulOutBuf_GetError(&UOB))
281 return "valid data check failed";
282
283 return NULL;
284}
285
286
287
288const char *UBMacroConversionsTest()
289{
290 char *szFoo = "foo";
291
292 UsefulBufC Foo = SZToUsefulBufC(szFoo);
293 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
294 return "SZToUsefulBufC failed";
295
296 UsefulBufC Too = SZLiteralToUsefulBufC("Toooo");
297 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
298 return "SZLiteralToUsefulBufC failed";
299
300 uint8_t pB[] = {0x42, 0x6f, 0x6f};
301 UsefulBufC Boo = ByteArrayLiteralToUsefulBufC(pB);
302 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
303 return "ByteArrayLiteralToUsefulBufC failed";
304
305 char *sz = "not const"; // some data for the test
306 UsefulBuf B = (UsefulBuf){sz, sizeof(sz)};
307 UsefulBufC BC = UsefulBufConst(B);
308 if(BC.len != sizeof(sz) || BC.ptr != sz)
309 return "UsefulBufConst failed";
310
311 return NULL;
312}
313
314
315const char *UBUtilTests()
316{
317 UsefulBuf UB = NULLUsefulBuf;
318
319 if(!UsefulBuf_IsNULL(UB)){
320 return "IsNull failed";
321 }
322
323 UsefulBufC UBC = UsefulBuf_Const(UB);
324
325 if(!UsefulBuf_IsNULL(UBC)){
326 return "IsNull const failed";
327 }
328
329 if(!UsefulBuf_IsEmpty(UBC)){
330 return "IsEmpty failed";
331 }
332
333 if(!UsefulBuf_IsNULLOrEmpty(UBC)){
334 return "IsNULLOrEmpty failed";
335 }
336
337 UB.ptr = "x"; // just some valid pointer
338
339 if(UsefulBuf_IsNULL(UB)){
340 return "IsNull failed";
341 }
342
343 if(!UsefulBuf_IsEmpty(UBC)){
344 return "IsEmpty failed";
345 }
346
347 // test the Unconst.
348 if(UsefulBufC_Unconst(UBC).ptr != NULL) {
349 return "Unconst failed";
350 }
351
352 // Set 100 bytes of '+'; validated a few tests later
353 MakeUsefulBufOnStack(Temp, 100);
354 UsefulBuf_Set(&Temp, '+');
355
356 // Try to copy into a buf that is too small and see failure
357 MakeUsefulBufOnStack(Temp2, 99);
358 if(!UsefulBuf_Copy(&Temp2, UsefulBuf_Const(Temp))) {
359 return "Copy should have failed";
360 }
361
362 // Try to copy into a NULL/empty buf and see failure
363 UsefulBuf UBNull = NULLUsefulBuf;
364 if(!UsefulBuf_Copy(&UBNull, UsefulBuf_Const(Temp))) {
365 return "Copy to NULL should have failed";
366 }
367
368 // Try to set a NULL/empty buf; nothing should happen
369 UsefulBuf_Set(&UBNull, '+'); // This will crash on failure
370
371 // Copy successfully to a buffer
372 MakeUsefulBufOnStack(Temp3, 101);
373 if(UsefulBuf_Copy(&Temp3, UsefulBuf_Const(Temp))) {
374 return "Copy should not have failed";
375 }
376
377 static const uint8_t pExpected[] = {
378 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
379 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
380 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
381 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
382 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
383 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
384 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
385 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
386 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
387 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
388 };
389 UsefulBufC Expected = ByteArrayLiteralToUsefulBufC(pExpected);
390 // This validates comparison for equality and the UsefulBuf_Set
391 if(UsefulBuf_Compare(Expected, UsefulBuf_Const(Temp))) {
392 return "Set / Copy / Compare failed";
393 }
394
395 // Compare two empties and expect success
396 if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
397 return "Compare Empties failed";
398 }
399
400 // Compare with empty and expect the first to be larger
401 if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
402 return "Compare with empty failed";
403 }
404
405
406 static const uint8_t pExpectedBigger[] = {
407 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
408 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
409 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
410 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
411 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
412 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
413 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
414 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
415 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
416 '+', '+', '+', '+', '+', '+', '+', '+', '+', ',',
417 };
418 UsefulBufC ExpectedBigger = ByteArrayLiteralToUsefulBufC(pExpectedBigger);
419
420 // Expect -1 with the first arg is smaller
421 if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
422 return "Compare with bigger";
423 }
424
425
426 static const uint8_t pExpectedSmaller[] = {
427 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
428 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
429 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
430 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
431 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
432 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
433 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
434 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
435 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
436 '+', '+', '+', '+', '+', '+', '+', '+', '+', '*',
437 };
438 UsefulBufC ExpectedSmaller = ByteArrayLiteralToUsefulBufC(pExpectedSmaller);
439 // Expect +1 with the first arg is larger
440 if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
441 return "Compare with smaller";
442 }
443
444
445 static const uint8_t pExpectedLonger[] = {
446 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
447 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
448 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
449 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
450 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
451 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
452 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
453 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
454 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
455 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+'
456 };
457 UsefulBufC ExpectedLonger = ByteArrayLiteralToUsefulBufC(pExpectedLonger);
458
459 // Expect -1 with the first arg is smaller
460 if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
461 return "Compare with longer";
462 }
463
464
465 static const uint8_t pExpectedShorter[] = {
466 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
467 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
468 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
469 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
470 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
471 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
472 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
473 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
474 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
475 '+', '+', '+', '+', '+', '+', '+', '+', '+',
476 };
477 UsefulBufC ExpectedShorter = ByteArrayLiteralToUsefulBufC(pExpectedShorter);
478 // Expect +1 with the first arg is larger
479 if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
480 return "Compare with shorter";
481 }
482
483
484 if(UsefulBuf_Copy(&Temp, NULLUsefulBufC)) {
485 return "Copy null/empty failed";
486 }
487
488 if(UsefulBuf_Compare(UsefulBuf_Const(Temp), NULLUsefulBufC)) {
489 return "Copy Null failed";
490 }
491
492 // Look for +++++... in +++++... and find it at the beginning
493 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
494 return "Failed to find";
495 }
496
497 // look for ++* in ....++* and find it at the end
498 static const uint8_t pToFind[] = {'+', '+', '*'};
499 UsefulBufC ToBeFound = ByteArrayLiteralToUsefulBufC(pToFind);
500
501 if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
502 return "Failed to find 2";
503 }
504
505 // look for ++* in ....++, and find it near the end
506 if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
507 return "Failed to not find";
508 }
509
510 // Look for the whole buffer in itself and succeed.
511 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
512 return "Failed to find 3";
513 }
514
515 return NULL;
516}
517
518
519const char * UBIntegerFormatTests()
520{
521 char outbuf[100];
522
523 UsefulOutBuf UOB;
524
525 const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
526 const uint64_t u64 = 1984738472938472;
527 const uint16_t u16 = 40000;
528 const uint8_t u8 = 9;
529 const float f = (float)314.15;
530 const double d = 2.1e10;
531
532 UsefulOutBuf_Init(&UOB, outbuf, sizeof(outbuf));
533
534 UsefulOutBuf_AppendUint32(&UOB, u32);
535 UsefulOutBuf_AppendUint64(&UOB, u64);
536 UsefulOutBuf_AppendUint16(&UOB, u16);
537 UsefulOutBuf_AppendByte(&UOB, u8);
538 UsefulOutBuf_AppendFloat(&UOB, f);
539 UsefulOutBuf_AppendDouble(&UOB, d);
540
541 UsefulBuf O;
542 if(UsefulOutBuf_OutUBuf(&UOB, &O))
543 return "Couldn't output integers";
544
545 // from https://en.wikipedia.org/wiki/Endianness
546 const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
547 if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
548 return "not in network order";
549 }
550
551 UsefulInputBuf UIB;
552
553 UsefulInputBuf_Init(&UIB, UsefulBuf_Const(O));
554
555 if(UsefulInputBuf_GetUint32(&UIB) != u32) {
556 return "u32 out then in failed";
557 }
558 if(UsefulInputBuf_GetUint64(&UIB) != u64) {
559 return "u64 out then in failed";
560 }
561 if(UsefulInputBuf_GetUint16(&UIB) != u16) {
562 return "u16 out then in failed";
563 }
564 if(UsefulInputBuf_GetByte(&UIB) != u8) {
565 return "u8 out then in failed";
566 }
567 if(UsefulInputBuf_GetFloat(&UIB) != f) {
568 return "float out then in failed";
569 }
570 if(UsefulInputBuf_GetDouble(&UIB) != d) {
571 return "double out then in failed";
572 }
573
574
575 return NULL;
576}
577
578
579