GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: test/test_frame.c Lines: 350 350 100.0 %
Date: 2020-12-10 21:44:00 Branches: 336 1080 31.1 %

Line Branch Exec Source
1
#include <stdio.h>
2
#include <arpa/inet.h>
3
#include <criterion/criterion.h>
4
5
#include "alloc.h"
6
#include "frame.h"
7
#include "rpmalloc.h"
8
9
24
static void setup(void) {
10
#ifdef USE_RPMALLOC
11
24
    rpmalloc_initialize();
12
#endif
13
24
}
14
15
24
static void teardown(void) {
16
#ifdef USE_RPMALLOC
17
24
    rpmalloc_finalize();
18
#endif
19
24
}
20
21
4
static inline char *mask(char key[4], char *payload, size_t length) {
22
    size_t i, j;
23


132404
    for (i = 0, j = 0; i < length; i++, j++){
24
132400
        payload[i] = payload[i] ^ key[j % 4];
25
    }
26
4
    return payload;
27
}
28
29
2
static inline uint64_t htons64(uint64_t value) {
30
2
	static const int num = 42;
31
32
	/**
33
	 * If this check is true, the system is using the little endian
34
	 * convention. Else the system is using the big endian convention, which
35
	 * means that we do not have to represent our integers in another way.
36
	 */
37
2
	if (*(char *)&num == 42) {
38
2
        return ((uint64_t)htonl((value) & 0xFFFFFFFFLL) << 32) | htonl((value) >> 32);
39
	} else {
40
        return value;
41
	}
42
}
43
44
TestSuite(WSS_parse_frame, .init = setup, .fini = teardown);
45
46
4
Test(WSS_parse_frame, null_payload) {
47
2
    size_t offset = 0;
48


2
    cr_assert(NULL == WSS_parse_frame(NULL, 0, &offset));
49
2
}
50
51
4
Test(WSS_parse_frame, empty_payload) {
52
2
    size_t offset = 0;
53


2
    cr_assert(NULL != WSS_parse_frame("", 0, &offset));
54


2
    cr_assert(offset == 2);
55
2
}
56
57
4
Test(WSS_parse_frame, small_client_frame) {
58
2
    size_t offset = 0;
59
2
    char *payload = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
60
2
    uint16_t length = strlen(payload);
61
2
    wss_frame_t *frame = WSS_parse_frame(payload, length, &offset);
62


2
    cr_assert(NULL != frame);
63


2
    cr_assert(offset == length);
64


2
    cr_assert(strncmp(frame->payload, "Hello", frame->payloadLength) == 0);
65
2
    WSS_free_frame(frame);
66
2
}
67
68
4
Test(WSS_parse_frame, medium_client_frame) {
69
2
    size_t offset = 0;
70
2
    char header[2] = "\x81\xFE";
71
2
    char key[4] = "\x37\xfa\x21\x3d";
72
2
    char *payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin hendrerit ornare tortor ut euismod. Nunc finibus convallis sem, at imperdiet ligula commodo id. Nam bibendum nec augue in posuere mauris.";
73
2
    uint16_t length = strlen(payload);
74
2
    char *payload_copy = WSS_copy(payload, length);
75
2
    char *payload_frame = WSS_malloc((2+2+4+length+1)*sizeof(char));
76
2
    uint16_t len = htons(length);
77
2
    memcpy(payload_frame, header, 2);
78
2
    memcpy(payload_frame+2, &len, 2);
79
2
    memcpy(payload_frame+2+2, key, 4);
80
4
    memcpy(payload_frame+2+2+4, mask(key, payload_copy, length), length);
81
2
    wss_frame_t *frame = WSS_parse_frame(payload_frame, length+8, &offset);
82


2
    cr_assert(NULL != frame);
83


2
    cr_assert(offset == 208);
84


2
    cr_assert(strncmp(frame->payload, payload, frame->payloadLength) == 0);
85
2
    WSS_free_frame(frame);
86
2
    WSS_free((void **)&payload_copy);
87
2
    WSS_free((void **)&payload_frame);
88
2
}
89
90
4
Test(WSS_parse_frame, large_client_frame) {
91
2
    int i;
92
2
    size_t offset = 0;
93
2
    char header[2] = "\x81\xFF";
94
2
    char key[4] = "\x37\xfa\x21\x3d";
95
2
    char *p = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin hendrerit ornare tortor ut euismod. Nunc finibus convallis sem, at imperdiet ligula commodo id. Nam bibendum nec augue in posuere mauris.";
96
2
    char *payload = WSS_malloc(66001);
97
2
    size_t plen = strlen(p);
98
2
    size_t poff = 0;
99
662
    for (i = 0; i < 330; i++) {
100
660
        memcpy(payload+poff, p, plen);
101
660
        poff+=plen;
102
    }
103
2
    uint64_t length = strlen(payload);
104
2
    char *payload_copy = WSS_copy(payload, length);
105
2
    char *payload_frame = WSS_malloc((2+2+4+length+1)*sizeof(char));
106
2
    uint64_t len = htons64(length);
107
2
    memcpy(payload_frame, header, 2);
108
2
    memcpy(payload_frame+2, &len, sizeof(uint64_t));
109
2
    memcpy(payload_frame+2+sizeof(uint64_t), key, 4);
110
4
    memcpy(payload_frame+2+sizeof(uint64_t)+4, mask(key, payload_copy, length), length);
111
2
    wss_frame_t *frame = WSS_parse_frame(payload_frame, length+6+sizeof(uint64_t), &offset);
112


2
    cr_assert(NULL != frame);
113


2
    cr_assert(offset == 66014);
114


2
    cr_assert(strncmp(frame->payload, payload, frame->payloadLength) == 0);
115
2
    WSS_free_frame(frame);
116
2
    WSS_free((void **)&payload);
117
2
    WSS_free((void **)&payload_copy);
118
2
    WSS_free((void **)&payload_frame);
119
2
}
120
121
TestSuite(WSS_stringify_frame, .init = setup, .fini = teardown);
122
123
4
Test(WSS_stringify_frame, null_frame) {
124
2
    char *message;
125


2
    cr_assert(0 == WSS_stringify_frame(NULL, &message));
126


2
    cr_assert(NULL == message);
127
2
}
128
129
4
Test(WSS_stringify_frame, small_client_frame) {
130
2
    size_t offset = 0;
131
2
    char *message;
132
2
    char *payload = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
133
2
    uint16_t length = strlen(payload);
134
135
2
    wss_frame_t *frame = WSS_parse_frame(payload, length, &offset);
136
137


2
    cr_assert(NULL != frame);
138


2
    cr_assert(offset == length);
139


2
    cr_assert(strncmp(frame->payload, "Hello", frame->payloadLength) == 0);
140
141
2
    offset = WSS_stringify_frame(frame, &message);
142
143


2
    cr_assert(offset == (size_t)length-4);
144


2
    cr_assert(strncmp(message, "\x81\x05", 2) == 0);
145


2
    cr_assert(strncmp(frame->payload, message+2, 5) == 0);
146
147
2
    WSS_free((void **)&message);
148
2
    WSS_free_frame(frame);
149
2
}
150
151
4
Test(WSS_stringify_frame, small_client_frame_rsv) {
152
2
    size_t offset = 0;
153
2
    char *message;
154
2
    char *payload = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
155
2
    uint16_t length = strlen(payload);
156
157
2
    wss_frame_t *frame = WSS_parse_frame(payload, length, &offset);
158
159


2
    cr_assert(NULL != frame);
160


2
    cr_assert(offset == length);
161


2
    cr_assert(strncmp(frame->payload, "Hello", frame->payloadLength) == 0);
162
163
2
    frame->rsv1 = true;
164
2
    frame->rsv2 = true;
165
2
    frame->rsv3 = true;
166
167
2
    offset = WSS_stringify_frame(frame, &message);
168
169


2
    cr_assert(offset == (size_t)length-4);
170


2
    cr_assert(strncmp(message, "\xF1\x05", 2) == 0);
171


2
    cr_assert(strncmp(frame->payload, message+2, 5) == 0);
172
173
2
    WSS_free((void **)&message);
174
2
    WSS_free_frame(frame);
175
2
}
176
177
4
Test(WSS_stringify_frame, medium_client_frame) {
178
2
    size_t offset = 0;
179
2
    char header[2] = "\x81\xFE";
180
2
    char *message;
181
2
    char key[4] = "\x37\xfa\x21\x3d";
182
2
    char *payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin hendrerit ornare tortor ut euismod. Nunc finibus convallis sem, at imperdiet ligula commodo id. Nam bibendum nec augue in posuere mauris.";
183
2
    uint16_t length = strlen(payload);
184
2
    char *payload_copy = WSS_copy(payload, length);
185
2
    char *payload_frame = WSS_malloc((2+2+4+length+1)*sizeof(char));
186
2
    uint16_t len = htons(length);
187
2
    memcpy(payload_frame, header, 2);
188
2
    memcpy(payload_frame+2, &len, 2);
189
2
    memcpy(payload_frame+2+2, key, 4);
190
4
    memcpy(payload_frame+2+2+4, mask(key, payload_copy, length), length);
191
2
    wss_frame_t *frame = WSS_parse_frame(payload_frame, length+8, &offset);
192


2
    cr_assert(NULL != frame);
193


2
    cr_assert(offset == 208);
194


2
    cr_assert(strncmp(frame->payload, payload, frame->payloadLength) == 0);
195
196
2
    offset = WSS_stringify_frame(frame, &message);
197
198


2
    cr_assert(offset == (size_t)length+2+sizeof(uint16_t));
199


2
    cr_assert(strncmp(message, "\x81\x7E", 2) == 0);
200
2
    uint16_t str_len;
201
2
    memcpy(&str_len, message+2, sizeof(uint16_t));
202


2
    cr_assert(str_len == len);
203


2
    cr_assert(strncmp(frame->payload, message+2+sizeof(uint16_t), length) == 0);
204
205
2
    WSS_free_frame(frame);
206
2
    WSS_free((void **)&message);
207
2
    WSS_free((void **)&payload_copy);
208
2
    WSS_free((void **)&payload_frame);
209
2
}
210
211
4
Test(WSS_stringify_frame, large_client_frame) {
212
2
    int i;
213
2
    size_t offset = 0;
214
2
    char *message;
215
2
    char header[2] = "\x81\xFF";
216
2
    char key[4] = "\x37\xfa\x21\x3d";
217
2
    char *p = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin hendrerit ornare tortor ut euismod. Nunc finibus convallis sem, at imperdiet ligula commodo id. Nam bibendum nec augue in posuere mauris.";
218
2
    char *payload = WSS_malloc(66001);
219
2
    size_t plen = strlen(p);
220
2
    size_t poff = 0;
221
662
    for (i = 0; i < 330; i++) {
222
660
        memcpy(payload+poff, p, plen);
223
660
        poff+=plen;
224
    }
225
2
    uint64_t length = strlen(payload);
226
2
    char *payload_copy = WSS_copy(payload, length);
227
2
    char *payload_frame = WSS_malloc((2+2+4+length+1)*sizeof(char));
228
2
    uint64_t len = htons64(length);
229
2
    memcpy(payload_frame, header, 2);
230
2
    memcpy(payload_frame+2, &len, sizeof(uint64_t));
231
2
    memcpy(payload_frame+2+sizeof(uint64_t), key, 4);
232
4
    memcpy(payload_frame+2+sizeof(uint64_t)+4, mask(key, payload_copy, length), length);
233
2
    wss_frame_t *frame = WSS_parse_frame(payload_frame, length+6+sizeof(uint64_t), &offset);
234


2
    cr_assert(NULL != frame);
235


2
    cr_assert(offset == 66014);
236


2
    cr_assert(strncmp(frame->payload, payload, frame->payloadLength) == 0);
237
238
2
    offset = WSS_stringify_frame(frame, &message);
239
240


2
    cr_assert(offset == (size_t)length+2+sizeof(uint64_t));
241


2
    cr_assert(strncmp(message, "\x81\x7F", 2) == 0);
242
2
    uint64_t str_len;
243
2
    memcpy(&str_len, message+2, sizeof(uint64_t));
244


2
    cr_assert(str_len == len);
245


2
    cr_assert(strncmp(frame->payload, message+2+sizeof(uint64_t), length) == 0);
246
247
2
    WSS_free_frame(frame);
248
2
    WSS_free((void **)&message);
249
2
    WSS_free((void **)&payload);
250
2
    WSS_free((void **)&payload_copy);
251
2
    WSS_free((void **)&payload_frame);
252
2
}
253
254
TestSuite(WSS_pong_frame, .init = setup, .fini = teardown);
255
256
4
Test(WSS_pong_frame, null_frame) {
257


2
    cr_assert(NULL == WSS_pong_frame(NULL));
258
2
}
259
260
4
Test(WSS_pong_frame, pong_from_ping) {
261
2
    wss_frame_t *ping = WSS_ping_frame();
262
2
    size_t ping_payload_len = ping->payloadLength;
263
2
    char *ping_payload = WSS_copy(ping->payload, ping_payload_len);
264
2
    wss_frame_t *pong = WSS_pong_frame(ping);
265
266


2
    cr_assert(NULL != pong);
267


2
    cr_assert(true == pong->fin);
268


2
    cr_assert(false == pong->rsv1);
269


2
    cr_assert(false == pong->rsv2);
270


2
    cr_assert(false == pong->rsv3);
271


2
    cr_assert(PONG_FRAME == pong->opcode);
272


2
    cr_assert(0 == pong->mask);
273


2
    cr_assert(0 == pong->maskingKey[0]);
274


2
    cr_assert(0 == pong->maskingKey[1]);
275


2
    cr_assert(0 == pong->maskingKey[2]);
276


2
    cr_assert(0 == pong->maskingKey[3]);
277


2
    cr_assert(pong->payloadLength == ping_payload_len);
278


2
    cr_assert(strncmp(pong->payload, ping_payload, ping_payload_len) == 0);
279
280
2
    WSS_free((void **)&ping_payload);
281
2
}
282
283
TestSuite(WSS_stringify_frames, .init = setup, .fini = teardown);
284
285
4
Test(WSS_stringify_frames, null_frame) {
286
2
    char *message;
287


2
    cr_assert(0 == WSS_stringify_frames(NULL, 0, &message));
288


2
    cr_assert(NULL == message);
289
2
}
290
291
4
Test(WSS_stringify_frames, null_last_frame) {
292
2
    size_t offset = 0;
293
2
    char *message;
294
2
    char *payload = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
295
2
    uint16_t length = strlen(payload);
296
2
    wss_frame_t *frames[2];
297
2
    wss_frame_t *frame = WSS_parse_frame(payload, length, &offset);
298
299


2
    cr_assert(NULL != frame);
300


2
    cr_assert(offset == length);
301


2
    cr_assert(strncmp(frame->payload, "Hello", frame->payloadLength) == 0);
302
303
2
    frames[0] = frame;
304
2
    frames[1] = NULL;
305
306


2
    cr_assert(0 == WSS_stringify_frames(frames, 2, &message));
307


2
    cr_assert(NULL == message);
308
2
    WSS_free_frame(frame);
309
2
}
310
311
4
Test(WSS_stringify_frames, small_client_frame) {
312
2
    size_t offset = 0;
313
2
    char *message;
314
2
    char *payload = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
315
2
    uint16_t length = strlen(payload);
316
317
2
    wss_frame_t *frame = WSS_parse_frame(payload, length, &offset);
318
319


2
    cr_assert(NULL != frame);
320


2
    cr_assert(offset == length);
321


2
    cr_assert(strncmp(frame->payload, "Hello", frame->payloadLength) == 0);
322
323
2
    offset = WSS_stringify_frames(&frame, 1, &message);
324
325


2
    cr_assert(offset == (size_t)length-4);
326


2
    cr_assert(strncmp(message, "\x81\x05", 2) == 0);
327


2
    cr_assert(strncmp(frame->payload, message+2, 5) == 0);
328
329
2
    WSS_free((void **)&message);
330
2
    WSS_free_frame(frame);
331
2
}
332
333
TestSuite(WSS_create_frames, .init = setup, .fini = teardown);
334
335
4
Test(WSS_create_frames, null_config) {
336
2
    wss_frame_t **frames;
337


2
    cr_assert(0 == WSS_create_frames(NULL, CLOSE_FRAME, "", 0, &frames));
338


2
    cr_assert(NULL == frames);
339
2
}
340
341
4
Test(WSS_create_frames, null_message_with_length) {
342
2
    wss_frame_t **frames;
343
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
344


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
345
346


2
    cr_assert(0 == WSS_create_frames(conf, CLOSE_FRAME, NULL, 1, &frames));
347


2
    cr_assert(NULL == frames);
348
2
    WSS_config_free(conf);
349
2
    WSS_free((void**) &conf);
350
2
}
351
352
4
Test(WSS_create_frames, zero_length) {
353
2
    wss_frame_t **frames;
354
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
355


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
356
357


2
    cr_assert(1 == WSS_create_frames(conf, TEXT_FRAME, "", 0, &frames));
358


2
    cr_assert(frames[0]->payloadLength == 0);
359
2
    WSS_config_free(conf);
360
2
    WSS_free((void**) &conf);
361
2
}
362
363
4
Test(WSS_create_frames, multiple_frames) {
364
2
    char *message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin hendrerit ornare tortor ut euismod. Nunc finibus convallis sem, at imperdiet ligula commodo id. Nam bibendum nec augue in posuere mauris.";
365
2
    wss_frame_t **frames;
366
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
367


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
368
369


2
    cr_assert(2 == WSS_create_frames(conf, TEXT_FRAME, message, strlen(message), &frames));
370


2
    cr_expect(frames[0]->payloadLength == conf->size_frame);
371


2
    cr_expect(frames[1]->payloadLength == strlen(message)-conf->size_frame);
372


2
    cr_expect(strncmp(frames[0]->payload, message, frames[0]->payloadLength) == 0);
373


2
    cr_expect(strncmp(frames[1]->payload, message+conf->size_frame, frames[1]->payloadLength) == 0);
374
375
2
    WSS_config_free(conf);
376
2
    WSS_free((void**) &conf);
377
2
}
378
379
4
Test(WSS_create_frames, empty_close_frame) {
380
2
    char *message = "";
381
2
    wss_frame_t **frames;
382
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
383


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
384
385


2
    cr_assert(1 == WSS_create_frames(conf, CLOSE_FRAME, message, 0, &frames));
386


2
    cr_assert(frames[0]->payloadLength == 2);
387


2
    cr_assert(frames[0]->opcode == CLOSE_FRAME);
388


2
    cr_assert(memcmp(frames[0]->payload, "\x03\xE8", frames[0]->payloadLength) == 0);
389
390
2
    WSS_config_free(conf);
391
2
    WSS_free((void**) &conf);
392
2
}
393
394
4
Test(WSS_create_frames, protocol_error_close_frame) {
395
2
    char *message = "\x03";
396
2
    wss_frame_t **frames;
397
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
398


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
399
400


2
    cr_assert(1 == WSS_create_frames(conf, CLOSE_FRAME, message, strlen(message), &frames));
401


2
    cr_assert(frames[0]->payloadLength == 2);
402


2
    cr_assert(frames[0]->opcode == CLOSE_FRAME);
403


2
    cr_assert(memcmp(frames[0]->payload, "\x03\xEA", frames[0]->payloadLength) == 0);
404
405
2
    WSS_config_free(conf);
406
2
    WSS_free((void**) &conf);
407
2
}
408
409
4
Test(WSS_create_frames, close_frame_with_opcode) {
410
2
    char *message = "\x03\xEA";
411
2
    wss_frame_t **frames;
412
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
413


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
414
415


2
    cr_assert(1 == WSS_create_frames(conf, CLOSE_FRAME, message, strlen(message), &frames));
416


2
    cr_assert(frames[0]->payloadLength == 2);
417


2
    cr_assert(frames[0]->opcode == CLOSE_FRAME);
418


2
    cr_assert(memcmp(frames[0]->payload, message, strlen(message)) == 0);
419
420
2
    WSS_config_free(conf);
421
2
    WSS_free((void**) &conf);
422
2
}
423
424
4
Test(WSS_create_frames, close_frame_with_opcode_and_reason) {
425
2
    char *message = "\x03\xEDThis is a test";
426
2
    wss_frame_t **frames;
427
2
    wss_config_t *conf = (wss_config_t *) WSS_malloc(sizeof(wss_config_t));
428


2
    cr_assert(WSS_SUCCESS == WSS_config_load(conf, "resources/test_wss.json"));
429
430


2
    cr_assert(1 == WSS_create_frames(conf, CLOSE_FRAME, message, strlen(message), &frames));
431


2
    cr_assert(frames[0]->payloadLength == 16);
432


2
    cr_assert(frames[0]->opcode == CLOSE_FRAME);
433


2
    cr_assert(memcmp(frames[0]->payload, message, strlen(message)) == 0);
434
435
2
    WSS_config_free(conf);
436
2
    WSS_free((void**) &conf);
437
2
}
438
439
TestSuite(WSS_closing_frame, .init = setup, .fini = teardown);
440
441
4
Test(WSS_closing_frame, create_different_closing_frames) {
442
2
    uint16_t code, nw_code;
443
2
    wss_frame_t *frame;
444
445
34
    for (int i = 0; i <= 15; i++) {
446
32
        code = CLOSE_NORMAL+i;
447
32
        nw_code = htons(code);
448
32
        frame = WSS_closing_frame(code, NULL);
449
450
32
        if (i == 4) {
451


2
            cr_assert(frame == NULL);
452
        } else {
453


30
            cr_assert(frame != NULL);
454


30
            cr_expect(frame->opcode == CLOSE_FRAME);
455


30
            cr_expect(memcmp(frame->payload, &nw_code, sizeof(nw_code)) == 0);
456


30
            cr_expect(frame->payloadLength > 2);
457
        }
458
459
32
        WSS_free_frame(frame);
460
    }
461
2
}
462