| /* |
| This file is part of libmicrohttpd |
| Copyright (C) 2021 David Gausmann |
| |
| libmicrohttpd is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published |
| by the Free Software Foundation; either version 3, or (at your |
| option) any later version. |
| |
| libmicrohttpd is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with libmicrohttpd; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| Boston, MA 02110-1301, USA. |
| */ |
| /** |
| * @file test_websocket.c |
| * @brief Testcase for WebSocket decoding/encoding |
| * @author David Gausmann |
| */ |
| #include "microhttpd.h" |
| #include "microhttpd_ws.h" |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <stdint.h> |
| #include <time.h> |
| |
| #if SIZE_MAX >= 0x100000000 |
| #define ENABLE_64BIT_TESTS 1 |
| #endif |
| |
| int disable_alloc = 0; |
| size_t open_allocs = 0; |
| |
| /** |
| * Custom `malloc()` function used for memory tests |
| */ |
| static void * |
| test_malloc (size_t buf_len) |
| { |
| if (0 != disable_alloc) |
| return NULL; |
| void *result = malloc (buf_len); |
| if (NULL != result) |
| ++open_allocs; |
| return result; |
| } |
| |
| |
| /** |
| * Custom `realloc()` function used for memory tests |
| */ |
| static void * |
| test_realloc (void *buf, size_t buf_len) |
| { |
| if (0 != disable_alloc) |
| return NULL; |
| void *result = realloc (buf, buf_len); |
| if ((NULL != result) && (NULL == buf)) |
| ++open_allocs; |
| return result; |
| } |
| |
| |
| /** |
| * Custom `free()` function used for memory tests |
| */ |
| static void |
| test_free (void *buf) |
| { |
| if (NULL != buf) |
| --open_allocs; |
| free (buf); |
| } |
| |
| |
| /** |
| * Custom `rng()` function used for client mode tests |
| */ |
| static size_t |
| test_rng (void *cls, void *buf, size_t buf_len) |
| { |
| for (size_t i = 0; i < buf_len; ++i) |
| { |
| ((char *) buf) [i] = (char) (rand () % 0xFF); |
| } |
| |
| return buf_len; |
| } |
| |
| |
| /** |
| * Helper function which allocates a big amount of data |
| */ |
| static void |
| allocate_length_test_data (char **buf1, |
| char **buf2, |
| size_t buf_len, |
| const char *buf1_prefix, |
| size_t buf1_prefix_len) |
| { |
| if (NULL != *buf1) |
| free (*buf1); |
| if (NULL != *buf2) |
| free (*buf2); |
| *buf1 = (char *) malloc (buf_len + buf1_prefix_len); |
| *buf2 = (char *) malloc (buf_len); |
| if ((NULL == buf1) || (NULL == buf2)) |
| return; |
| memcpy (*buf1, |
| buf1_prefix, |
| buf1_prefix_len); |
| for (size_t i = 0; i < buf_len; i += 64) |
| { |
| size_t bytes_to_copy = buf_len - i; |
| if (64 < bytes_to_copy) |
| bytes_to_copy = 64; |
| memcpy (*buf1 + i + buf1_prefix_len, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-", |
| bytes_to_copy); |
| memcpy (*buf2 + i, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-", |
| bytes_to_copy); |
| } |
| } |
| |
| |
| /** |
| * Helper function which performs a single decoder test |
| */ |
| static int |
| test_decode_single (unsigned int test_line, |
| int flags, size_t max_payload_size, size_t decode_count, |
| size_t buf_step, |
| const char *buf, size_t buf_len, |
| const char *expected_payload, size_t expected_payload_len, |
| int expected_return, int expected_valid, size_t |
| expected_streambuf_read_len) |
| { |
| struct MHD_WebSocketStream *ws = NULL; |
| int ret = MHD_WEBSOCKET_STATUS_OK; |
| |
| /* initialize stream */ |
| ret = MHD_websocket_stream_init2 (&ws, |
| flags, |
| max_payload_size, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Allocation failed for decode test in line %u.\n", |
| (unsigned int) test_line); |
| return 1; |
| } |
| |
| /* perform decoding in a loop */ |
| size_t streambuf_read_len = 0; |
| size_t payload_len = 0; |
| char *payload = NULL; |
| for (size_t i = 0; i < decode_count; ++i) |
| { |
| size_t streambuf_read_len_ = 0; |
| size_t bytes_to_take = buf_len - streambuf_read_len; |
| if ((0 != buf_step) && (buf_step < bytes_to_take)) |
| bytes_to_take = buf_step; |
| ret = MHD_websocket_decode (ws, buf + streambuf_read_len, bytes_to_take, |
| &streambuf_read_len_, &payload, &payload_len); |
| streambuf_read_len += streambuf_read_len_; |
| if (i + 1 < decode_count) |
| { |
| if (payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| payload_len = 0; |
| } |
| } |
| } |
| |
| /* check the (last) result */ |
| if (ret != expected_return) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The return value should be %d, but is %d\n", |
| (unsigned int) test_line, |
| (int) expected_return, |
| (int) ret); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| if (payload_len != expected_payload_len) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The payload_len should be %u, but is %u\n", |
| (unsigned int) test_line, |
| (unsigned int) expected_payload_len, |
| (unsigned int) payload_len); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| if (0 != payload_len) |
| { |
| if (NULL == payload) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The payload is NULL\n", |
| (unsigned int) test_line); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| else if (NULL == expected_payload) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The expected_payload is NULL (wrong test declaration)\n", |
| (unsigned int) test_line); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| else if (0 != memcmp (payload, expected_payload, payload_len)) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The payload differs from the expected_payload\n", |
| (unsigned int) test_line); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| } |
| else |
| { |
| if (NULL != payload) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The payload is not NULL, but payload_len is 0\n", |
| (unsigned int) test_line); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| else if (NULL != expected_payload) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The expected_payload is not NULL, but expected_payload_len is 0 (wrong test declaration)\n", |
| (unsigned int) test_line); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| } |
| if (streambuf_read_len != expected_streambuf_read_len) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The streambuf_read_len should be %u, but is %u\n", |
| (unsigned int) test_line, |
| (unsigned int) expected_streambuf_read_len, |
| (unsigned int) streambuf_read_len); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| ret = MHD_websocket_stream_is_valid (ws); |
| if (ret != expected_valid) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u: The stream validity should be %u, but is %u\n", |
| (unsigned int) test_line, |
| (int) expected_valid, |
| (int) ret); |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| return 1; |
| } |
| |
| /* cleanup */ |
| MHD_websocket_free (ws, payload); |
| MHD_websocket_stream_free (ws); |
| |
| return 0; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_stream_init()` and |
| * `MHD_websocket_stream_init2()` |
| */ |
| int |
| test_inits () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *ws; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| All valid flags |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: all valid flags for init (only the even ones work) */ |
| for (int i = 0; i < 7; ++i) |
| { |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| i, |
| 0); |
| if (((0 == (i & MHD_WEBSOCKET_FLAG_CLIENT)) && |
| ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws))) || |
| ((0 != (i & MHD_WEBSOCKET_FLAG_CLIENT)) && |
| ((MHD_WEBSOCKET_STATUS_OK == ret) || |
| (NULL != ws)))) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for flags %d.\n", |
| (unsigned int) __LINE__, |
| (int) i); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| } |
| /* Regular test: all valid flags for init2 */ |
| for (int i = 0; i < 7; ++i) |
| { |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| i, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| test_rng); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for flags %d.\n", |
| (unsigned int) __LINE__, |
| (int) i); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| } |
| /* Fail test: Invalid flags for init */ |
| for (int i = 4; i < 32; ++i) |
| { |
| int flags = 1 << i; |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| flags, |
| 0); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for invalid flags %d.\n", |
| (unsigned int) __LINE__, |
| (int) flags); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| } |
| /* Fail test: Invalid flag for init2 */ |
| for (int i = 4; i < 32; ++i) |
| { |
| int flags = 1 << i; |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| flags, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for invalid flags %d.\n", |
| (unsigned int) __LINE__, |
| (int) flags); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| max_payload_size |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: max_payload_size = 0 for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: max_payload_size = 0 for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Edge test (success): max_payload_size = 1 for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 1); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 1.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Edge test (success): max_payload_size = 1 for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 1, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 1.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: max_payload_size = 1000 for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 1000); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 1000.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: max_payload_size = 1000 for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 1000, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 1000.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| #ifdef ENABLE_64BIT_TESTS |
| /* Edge test (success): max_payload_size = 0x7FFFFFFFFFFFFFFF for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| (uint64_t) 0x7FFFFFFFFFFFFFFF); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0x7FFFFFFFFFFFFFFF.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Edge test (success): max_payload_size = 0x7FFFFFFFFFFFFFFF for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| (uint64_t) 0x7FFFFFFFFFFFFFFF, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0x7FFFFFFFFFFFFFFF.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Edge test (fail): max_payload_size = 0x8000000000000000 for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| (uint64_t) 0x8000000000000000); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0x8000000000000000.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Edge test (fail): max_payload_size = 0x8000000000000000 for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| (uint64_t) 0x8000000000000000, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u for max_payload_size 0x8000000000000000.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| #endif |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: websocket stream variable missing for init */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init (NULL, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Fail test: websocket stream variable missing for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (NULL, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Fail test: malloc missing for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| NULL, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Fail test: realloc missing for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| NULL, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Fail test: free missing for init2 */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| NULL, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: rng given for server mode (will be ignored) */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| test_rng); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: cls_rng given for server mode (will be ignored) */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| (void *) 12345, |
| test_rng); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Regular test: rng given for client mode */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| test_rng); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL == ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| /* Fail test: rng not given for client mode */ |
| ws = NULL; |
| ret = MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != ws) ) |
| { |
| fprintf (stderr, |
| "Init test failed in line %u %u.\n", |
| (unsigned int) __LINE__, ret); |
| ++failed; |
| } |
| if (NULL != ws) |
| { |
| MHD_websocket_stream_free (ws); |
| ws = NULL; |
| } |
| |
| return failed != 0 ? 0x01 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_create_accept_header()` |
| */ |
| int |
| test_accept () |
| { |
| int failed = 0; |
| char accept_key[29]; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| accepting |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Test case from RFC6455 4.2.2 */ |
| memset (accept_key, 0, 29); |
| ret = MHD_websocket_create_accept_header ("dGhlIHNhbXBsZSBub25jZQ==", |
| accept_key); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != memcmp (accept_key, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", 29))) |
| { |
| fprintf (stderr, |
| "Accept test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: missing sec-key value */ |
| memset (accept_key, 0, 29); |
| ret = MHD_websocket_create_accept_header (NULL, |
| accept_key); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "Accept test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: missing accept variable */ |
| memset (accept_key, 0, 29); |
| ret = MHD_websocket_create_accept_header ("dGhlIHNhbXBsZSBub25jZQ==", |
| NULL); |
| if (MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) |
| { |
| fprintf (stderr, |
| "Accept test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x02 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_decode()` |
| */ |
| int |
| test_decodes () |
| { |
| int failed = 0; |
| char *buf1 = NULL, *buf2 = NULL; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| text frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Masked text frame from RFC 6455, must succeed for server */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58", |
| 11, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Unmasked text frame from RFC 6455, must succeed for client */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x05\x48\x65\x6c\x6c\x6f", |
| 7, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Fail test: Unmasked text frame from RFC 6455, must fail for server */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x05\x48\x65\x6c\x6c\x6f", |
| 7, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Masked text frame from RFC 6455, must fail for client */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Text frame with UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x90\x00\x00\x00\x00" "This is my n" |
| "\xC3\xB6" "te", |
| 22, |
| "This is my n" "\xC3\xB6" "te", |
| 16, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 22); |
| /* Fail test: Text frame with with invalid UTF-8 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8F\x00\x00\x00\x00" "This is my n" "\xFF" |
| "te", |
| 21, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 18); |
| /* Fail test: Text frame with broken UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8F\x00\x00\x00\x00" "This is my n" "\xC3" |
| "te", |
| 21, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 19); |
| /* Regular test: Text frame without payload and mask (caller = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x80\x01\x02\x03\x04", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Fail test: Text frame without payload and no mask (caller = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Text frame without payload and mask (caller = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 2); |
| /* Fail test: Text frame without payload and no mask (caller = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x80\x01\x02\x03\x04", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| binary frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Masked binary frame (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58", |
| 11, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Unmasked binary frame (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x05\x48\x65\x6c\x6c\x6f", |
| 7, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Fail test: Unmasked binary frame (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x05\x48\x65\x6c\x6c\x6f", |
| 7, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Masked binary frame (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Binary frame without payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Regular test: Fragmented binary frame without payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 12); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x02\x80\x00\x00\x00\x00\x80\x80\x00\x00\x00\x00", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 12); |
| /* Regular test: Fragmented binary frame with payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06", |
| 18, |
| "\x01\x02\x03\x04\x05\x06", |
| 6, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 18); |
| /* Regular test: Fragmented binary frame with payload, fragments to the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06", |
| 18, |
| "\x01\x02\x03", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 9); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x80\x83\x00\x00\x00\x00\x04\x05\x06", |
| 18, |
| "\x04\x05\x06", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 18); |
| /* Regular test: Fragmented binary frame with payload, fragments to the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C", |
| 36, |
| "\x01\x02\x03", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 9); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C", |
| 36, |
| "\x04\x05\x06", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_NEXT_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 18); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 3rd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C", |
| 36, |
| "\x07\x08\x09", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_NEXT_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 27); |
| /* Regular test: Fragmented binary frame without payload, fragments to the caller, 4th call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 4, |
| 0, |
| "\x02\x83\x00\x00\x00\x00\x01\x02\x03\x00\x83\x00\x00\x00\x00\x04\x05\x06\x00\x83\x00\x00\x00\x00\x07\x08\x09\x80\x83\x00\x00\x00\x00\x0A\x0B\x0C", |
| 36, |
| "\x0A\x0B\x0C", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 36); |
| /* Regular test: Binary frame with bytes which look like invalid UTF-8 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x85\x00\x00\x00\x00" "Hell\xf6", |
| 11, |
| "Hell\xf6", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Binary frame with bytes which look like broken UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x85\x00\x00\x00\x00" "H\xC3llo", |
| 11, |
| "H\xC3llo", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Binary frame with bytes which look like valid UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x82\x85\x00\x00\x00\x00" "H\xC3\xA4lo", |
| 11, |
| "H\xC3\xA4lo", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x82\x00\x00\x00\x00" "H\xC3" |
| "\x80\x83\x00\x00\x00\x00" "\xA4lo", |
| 17, |
| "H\xC3\xA4lo", |
| 5, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence, |
| fragments to the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x02\x82\x00\x00\x00\x00" "H\xC3" |
| "\x80\x83\x00\x00\x00\x00" "\xA4lo", |
| 17, |
| "H\xC3", |
| 2, |
| MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 8); |
| /* Regular test: Fragmented binary frame with bytes which look like valid UTF-8 sequence, |
| fragments to the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x02\x82\x00\x00\x00\x00" "H\xC3" |
| "\x80\x83\x00\x00\x00\x00" "\xA4lo", |
| 17, |
| "\xA4lo", |
| 3, |
| MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| close frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Close frame with no payload but with mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 6); |
| /* Regular test: Close frame with no payload (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 2); |
| /* Fail test: Close frame with no payload and no mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Close frame with no payload but with mask (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Close frame with 2 byte payload for close reason */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x82\x00\x00\x00\x00\x03\xEB", |
| 8, |
| "\x03\xEB", |
| 2, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 8); |
| /* Fail test: Close frame with 1 byte payload (no valid close reason) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x81\x00\x00\x00\x00\x03", |
| 7, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Close frame with close reason and UTF-8 description */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x95\x00\x00\x00\x00\x03\xEB" |
| "Something was wrong", |
| 27, |
| "\x03\xEB" "Something was wrong", |
| 21, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 27); |
| /* Regular test: Close frame with close reason and UTF-8 description (with UTF-8 sequence) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x96\x00\x00\x00\x00\x03\xEB" |
| "Something was wr" "\xC3\xB6" "ng", |
| 28, |
| "\x03\xEB" "Something was wr" "\xC3\xB6" "ng", |
| 22, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 28); |
| /* Fail test: Close frame with close reason and invalid UTF-8 in description */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x95\x00\x00\x00\x00\x03\xEB" |
| "Something was wr" "\xFF" "ng", |
| 27, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 24); |
| /* Fail test: Close frame with close reason and broken UTF-8 sequence in description */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x95\x00\x00\x00\x00\x03\xEB" |
| "Something was wr" "\xC3" "ng", |
| 27, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 25); |
| /* Edge test (success): Close frame with 125 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFD\x00\x00\x00\x00\x03\xEB" |
| "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. :-)", |
| 131, |
| "\x03\xEB" |
| "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. :-)", |
| 125, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 131); |
| /* Edge test (failure): Close frame with 126 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFE\x00\x7e\x00\x00\x00\x00\x03\xEB" |
| "Something was wrong, so I decided to close this websocket. I hope you are not angry. But this is also the 123 cap test. >:-)", |
| 134, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Close frame with 500 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFE\x01\xf4\x00\x00\x00\x00\x03\xEB" |
| "The payload of this test isn't parsed.", |
| 49, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Edge test (failure): Close frame with 65535 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFE\xff\xff\x00\x00\x00\x00\x03\xEB" |
| "The payload of this test isn't parsed.", |
| 49, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Edge test (failure): Close frame with 65536 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFF\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xEB" |
| "The payload of this test isn't parsed.", |
| 54, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Close frame with 1000000 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\xFF\x00\x00\x00\x00\x00\x0F\x42\x40\x00\x00\x00\x00\x03\xEB" |
| "The payload of this test isn't parsed.", |
| 54, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| ping frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Ping frame with no payload but with mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Regular test: Ping frame with no payload (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 2); |
| /* Fail test: Ping frame with no payload and no mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Ping frame with no payload but with mask (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Ping frame with some (masked) payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x88\x01\x20\x03\x40\xFF\xFF\xFF\xFF\x00\x00\x00\x00", |
| 14, |
| "\xFE\xDF\xFC\xBF\x01\x20\x03\x40", |
| 8, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 14); |
| /* Edge test (success): Ping frame with one byte of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x81\x00\x00\x00\x00" "a", |
| 7, |
| "a", |
| 1, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Edge test (success): Ping frame with 125 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\xFD\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 131, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 131); |
| /* Edge test (fail): Ping frame with 126 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\xFE\x00\x7E\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 134, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Ping frame with UTF-8 data */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x90\x00\x00\x00\x00" "Ping is bin" |
| "\xC3\xA4" "ry.", |
| 22, |
| "Ping is bin" "\xC3\xA4" "ry.", |
| 16, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 22); |
| /* Regular test: Ping frame with invalid UTF-8 data */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x8F\x00\x00\x00\x00" "Ping is bin" "\xFF" |
| "ry.", |
| 21, |
| "Ping is bin" "\xFF" "ry.", |
| 15, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 21); |
| /* Regular test: Ping frame with broken UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x8F\x00\x00\x00\x00" "Ping is bin" "\xC3" |
| "ry.", |
| 21, |
| "Ping is bin" "\xC3" "ry.", |
| 15, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 21); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| pong frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Pong frame with no payload but with mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Regular test: Pong frame with no payload (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 2); |
| /* Fail test: Pong frame with no payload and no mask (decoder = server) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x00", |
| 2, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Fail test: Pong frame with no payload but with mask (decoder = client) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_CLIENT |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Pong frame with some (masked) payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x88\x01\x20\x03\x40\xFF\xFF\xFF\xFF\x00\x00\x00\x00", |
| 14, |
| "\xFE\xDF\xFC\xBF\x01\x20\x03\x40", |
| 8, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 14); |
| /* Edge test (success): Pong frame with one byte of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x81\x00\x00\x00\x00" "a", |
| 7, |
| "a", |
| 1, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Edge test (success): Pong frame with 125 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\xFD\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 131, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 131); |
| /* Edge test (fail): Pong frame with 126 bytes of payload */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\xFE\x00\x7E\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 134, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 1); |
| /* Regular test: Pong frame with UTF-8 data */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x90\x00\x00\x00\x00" "Pong is bin" |
| "\xC3\xA4" "ry.", |
| 22, |
| "Pong is bin" "\xC3\xA4" "ry.", |
| 16, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 22); |
| /* Regular test: Pong frame with invalid UTF-8 data */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x8F\x00\x00\x00\x00" "Pong is bin" "\xFF" |
| "ry.", |
| 21, |
| "Pong is bin" "\xFF" "ry.", |
| 15, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 21); |
| /* Regular test: Pong frame with broken UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8A\x8F\x00\x00\x00\x00" "Pong is bin" "\xC3" |
| "ry.", |
| 21, |
| "Pong is bin" "\xC3" "ry.", |
| 15, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 21); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| fragmentation |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Fragmented, masked text frame, we are the server and don't want fragments as caller */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58", |
| 17, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented, masked text frame, we are the server and don't want fragments as caller, but call decode two times */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, one call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58", |
| 17, |
| "Hel", |
| 3, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 9); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, second call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58", |
| 17, |
| "lo", |
| 2, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, third call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x3d\x37\xfa\x21\x51\x58", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58", |
| 23, |
| "Hel", |
| 3, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 9); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58", |
| 23, |
| "l", |
| 1, |
| MHD_WEBSOCKET_STATUS_TEXT_NEXT_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Regular test: Fragmented, masked text frame, we are the server and want fragments, 3rd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x00\x81\x3d\x37\xfa\x21\x51\x80\x81\x37\x37\xfa\x21\x58", |
| 23, |
| "o", |
| 1, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 23); |
| |
| |
| /* |
| ------------------------------------------------------------------------------ |
| invalid flags |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Template with valid data for the next tests (this one must succeed) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Fail test: RSV1 flag set */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x91\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: RSV2 flag set */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\xA1\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: RSV3 flag set */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\xC1\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| invalid opcodes |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: Invalid opcode 0 (0 is usually valid, but only if there was a data frame before) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x80\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 3 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x83\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 4 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x84\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 5 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x85\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 6 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x86\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 7 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x87\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 0x0B */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8B\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 0x0C */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8c\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 0x0D */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8d\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 0x0E */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8e\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Invalid opcode 0x0F */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x8f\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| |
| |
| /* |
| ------------------------------------------------------------------------------ |
| control frames without FIN flag |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: Close frame without FIN flag */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x08\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Ping frame without FIN flag */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x09\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Fail test: Pong frame without FIN flag */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x0a\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| length checks (without max_payload_len) |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): 0 bytes of payload (requires 1 byte length) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x80\x00\x00\x00\x00", |
| 6, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 6); |
| /* Edge test (success): 1 byte of payload (requires 1 byte length) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x81\x00\x00\x00\x00" "a", |
| 7, |
| "a", |
| 1, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Edge test (success): 125 bytes of payload (requires 1 byte length) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xfd\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 131, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 131); |
| /* Edge test (success): 126 bytes of payload (requires 2 byte length) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xfe\x00\x7e\x00\x00\x00\x00" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 134, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 126, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 134); |
| /* Edge test (success): 65535 bytes of payload (requires 2 byte length) */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65535, |
| "\x81\xfe\xff\xff\x00\x00\x00\x00", |
| 8); |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| buf1, |
| 65535 + 8, |
| buf2, |
| 65535, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 65535 + 8); |
| /* Edge test (success): 65536 bytes of payload (requires 8 byte length) */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65536, |
| "\x81\xff\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", |
| 14); |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| buf1, |
| 65536 + 14, |
| buf2, |
| 65536, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 65536 + 14); |
| /* Regular test: 1 MB of payload */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 1048576, |
| "\x81\xff\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", |
| 14); |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| buf1, |
| 1048576 + 14, |
| buf2, |
| 1048576, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 1048576 + 14); |
| /* Regular test: 100 MB of payload */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 104857600, |
| "\x81\xff\x00\x00\x00\x00\x06\x40\x00\x00\x00\x00\x00\x00", |
| 14); |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| buf1, |
| 104857600 + 14, |
| buf2, |
| 104857600, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 104857600 + 14); |
| if (NULL != buf1) |
| { |
| free (buf1); |
| buf1 = NULL; |
| } |
| if (NULL != buf2) |
| { |
| free (buf2); |
| buf2 = NULL; |
| } |
| #ifdef ENABLE_64BIT_TESTS |
| /* Edge test (success): Maximum allowed length (here is only the header checked) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\x7f\xff\xff\xff\xff\xff\xff\xff", |
| 10, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 10); |
| #else |
| /* Edge test (fail): Maximum allowed length |
| (the size is allowed, but the system cannot handle this amount of memory) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\x7f\xff\xff\xff\xff\xff\xff\xff", |
| 10, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| #endif |
| /* Edge test (fail): Too big payload length */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\x80\x00\x00\x00\x00\x00\x00\x00", |
| 10, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| /* Edge test (fail): Too big payload length */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\xff\xff\xff\xff\xff\xff\xff\xff", |
| 10, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| /* Fail test: Not the smallest payload length syntax used (2 byte instead of 1 byte) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xfe\x00\x05\x00\x00\x00\x00" "abcde", |
| 13, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 4); |
| /* Fail test: Not the smallest payload length syntax used (8 byte instead of 1 byte) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00" |
| "abcde", |
| 13, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| /* Fail test: Not the smallest payload length syntax used (8 byte instead of 2 byte) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\xff\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00" |
| "abcde", |
| 13, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| length checks (with max_payload_len) |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Frame with less payload than specified as limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 100, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Edge test (success): Frame with the same payload as the specified limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 5, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Edge test (fail): Frame with more payload than specified as limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 4, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 2); |
| /* Regular test: Fragmented frames with the sum of payload less than specified as limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 100, |
| 1, |
| 0, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Edge test (success): Fragmented frames with the sum of payload equal to the specified limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 5, |
| 1, |
| 0, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Edge test (fail): Fragmented frames with the sum of payload more than specified as limit */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 4, |
| 1, |
| 0, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 15); |
| /* Edge test (success): Fragmented frames with the sum of payload greater than |
| the specified limit, but we take fragments (one call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 5, |
| 1, |
| 0, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| "Hel", |
| 3, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 9); |
| /* Edge test (success): Fragmented frames with the sum of payload greater than |
| the specified limit, but we take fragments (two calls) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 5, |
| 2, |
| 0, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| "lo", |
| 2, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| UTF-8 sequences |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: No UTF-8 characters */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 a ", |
| 16, |
| " a ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Fail test: A UTF-8 tail character without sequence start character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xA4 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Regular test: A two byte UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xC3\xA4 ", |
| 16, |
| " \xC3\xA4 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Fail test: A broken two byte UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xC3 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Fail test: A two byte UTF-8 sequence with one UTF-8 tail too much */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xC3\xA4\xA4 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 9); |
| /* Regular test: A three byte UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\x8F\x8F ", |
| 16, |
| " \xEF\x8F\x8F ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Fail test: A broken byte UTF-8 sequence (two of three bytes) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 9); |
| /* Fail test: A broken byte UTF-8 sequence (one of three bytes) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Fail test: A three byte UTF-8 sequence followed by one UTF-8 tail byte */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| /* Regular test: A four byte UTF-8 sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F\x8F ", |
| 16, |
| " \xF2\x8F\x8F\x8F ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Fail test: A broken four byte UTF-8 sequence (three of four bytes) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 10); |
| /* Fail test: A broken four byte UTF-8 sequence (two of four bytes) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF2\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 9); |
| /* Fail test: A broken four byte UTF-8 sequence (one of four bytes) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF2 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Fail test: A four byte UTF-8 sequence followed by UTF-8 tail */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF2\x8F\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 11); |
| /* Fail test: A five byte UTF-8 sequence (only up to four bytes allowed) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xFB\x8F\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Fail test: A six byte UTF-8 sequence (only up to four bytes allowed) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xFD\x8F\x8F\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Fail test: A seven byte UTF-8 sequence (only up to four bytes allowed) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xFE\x8F\x8F\x8F\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Fail test: A eight byte UTF-8 sequence (only up to four bytes allowed) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xFF\x8F\x8F\x8F\x8F\x8F\x8F\x8F ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Edge test (success): The maximum allowed UTF-8 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF4\x8F\xBF\xBF ", |
| 16, |
| " \xF4\x8F\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The maximum allowed UTF-8 character + 1 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF4\x90\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The last valid UTF8-1 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \x7F ", |
| 16, |
| " \x7F ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the last valid UTF8-1 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Edge test (fail): The value before the first valid UTF8-2 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xC1\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Edge test (success): The first valid UTF8-2 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xC2\x80 ", |
| 16, |
| " \xC2\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-2 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xDF\xBF ", |
| 16, |
| " \xDF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the lst valid UTF8-2 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE0\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): The value before the first valid UTF8-3 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE0\x9F\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-3 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE0\xA0\x80 ", |
| 16, |
| " \xE0\xA0\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-3 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE0\xBF\xBF ", |
| 16, |
| " \xE0\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the first valid UTF8-3 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE0\xC0\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-3 character (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xE1\x80\x80 ", |
| 16, |
| " \xE1\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-3 character (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEC\xBF\xBF ", |
| 16, |
| " \xEC\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the last valid UTF8-3 character (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEC\xC0\xBF ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): The value before the first valid UTF8-3 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xED\x7F\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-3 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xED\x80\x80 ", |
| 16, |
| " \xED\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-3 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xED\x9F\xBF ", |
| 16, |
| " \xED\x9F\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the last valid UTF8-3 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xED\xA0\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): The value before the first valid UTF8-3 character (tail 4) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEE\x7F\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-3 character (tail 4) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEE\x80\x80 ", |
| 16, |
| " \xEE\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-3 character (tail 4) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\xBF\xBF ", |
| 16, |
| " \xEF\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the last valid UTF8-3 character (tail 4) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\xBF\xC0 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 9); |
| /* Edge test (fail): The value after the last valid UTF8-3 character (tail 4) #2 */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xEF\xC0\xBF ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): The value before the first valid UTF8-4 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF0\x8F\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-4 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF0\x90\x80\x80 ", |
| 16, |
| " \xF0\x90\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-4 character (tail 1) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF0\xBF\xBF\xBF ", |
| 16, |
| " \xF0\xBF\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The first valid UTF8-4 character (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF1\x80\x80\x80 ", |
| 16, |
| " \xF1\x80\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-4 character (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF3\xBF\xBF\xBF ", |
| 16, |
| " \xF3\xBF\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): A value before the last valid UTF8-4 character in the second byte (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF3\x7F\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): A value after the last valid UTF8-4 character in the second byte (tail 2) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF3\xC0\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (success): The first valid UTF8-4 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF4\x80\x80\x80 ", |
| 16, |
| " \xF4\x80\x80\x80 ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (success): The last valid UTF8-4 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF4\x8F\xBF\xBF ", |
| 16, |
| " \xF4\x8F\xBF\xBF ", |
| 10, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 16); |
| /* Edge test (fail): The value after the last valid UTF8-4 character (tail 3) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF4\x90\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 8); |
| /* Edge test (fail): The first byte value the last valid UTF8-4 character */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x8A\x00\x00\x00\x00 \xF5\x90\x80\x80 ", |
| 16, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Unfinished UTF-8 sequence between fragmented text frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: UTF-8 sequence between fragments, no fragmentation for the caller */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x8D\x00\x00\x00\x00" "This is my n" |
| "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te", |
| 28, |
| "This is my n" "\xC3\xB6" "te", |
| 16, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 28); |
| /* Regular test: UTF-8 sequence between fragments, fragmentation for the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x8D\x00\x00\x00\x00" "This is my n" |
| "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te", |
| 28, |
| "This is my n", |
| 12, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 19); |
| /* Regular test: UTF-8 sequence between fragments, fragmentation for the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x8D\x00\x00\x00\x00" "This is my n" |
| "\xC3\x80\x83\x00\x00\x00\x00\xB6" "te", |
| 28, |
| "\xC3\xB6" "te", |
| 4, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 28); |
| /* Edge test (success): UTF-8 sequence between fragments, but nothing before, fragmentation for the caller, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x81\x00\x00\x00\x00\xC3\x80\x81\x00\x00\x00\x00\xB6", |
| 14, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 7); |
| /* Edge test (success): UTF-8 sequence between fragments, but nothing before, fragmentation for the caller, 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x81\x00\x00\x00\x00\xC3\x80\x81\x00\x00\x00\x00\xB6", |
| 14, |
| "\xC3\xB6", |
| 2, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 14); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Decoding with broken stream |
| ------------------------------------------------------------------------------ |
| */ |
| /* Failure test: Invalid sequence */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\xFF\x81\x85\x00\x00\x00\x00" "Hello", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Failure test: Call after invalidated stream */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\xFF\x81\x85\x00\x00\x00\x00" "Hello", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_STREAM_BROKEN, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Failure test: Call after invalidated stream (but with different buffer) */ |
| { |
| struct MHD_WebSocketStream *ws; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0)) |
| { |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| ret = MHD_websocket_decode (ws, |
| "\xFF", |
| 1, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if (MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR != ret) |
| { |
| fprintf (stderr, |
| "Test failed in line %u: The return value should be -1, but is %d\n", |
| (unsigned int) __LINE__, |
| (int) ret); |
| ++failed; |
| } |
| else |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if (MHD_WEBSOCKET_STATUS_STREAM_BROKEN != ret) |
| { |
| fprintf (stderr, |
| "Test failed in line %u: The return value should be -2, but is %d\n", |
| (unsigned int) __LINE__, |
| (int) ret); |
| ++failed; |
| } |
| } |
| MHD_websocket_stream_free (ws); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Individual test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| frame after close frame |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x81\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 6); |
| /* Failure test: Text frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x81\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 6); |
| /* Failure test: Binary frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x82\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 6); |
| /* Failure test: Continue frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x80\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 6); |
| /* Regular test: Ping frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x89\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 17); |
| /* Regular test: Pong frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x8A\x85\x00\x00\x00\x00" |
| "Hello", |
| 17, |
| "Hello", |
| 5, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 17); |
| /* Regular test: Close frame after close frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x88\x80\x00\x00\x00\x00\x88\x80\x00\x00\x00\x00", |
| 12, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 12); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| decoding byte-by-byte |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Text frame, 2 bytes per loop, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 2, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 2); |
| /* Regular test: Text frame, 2 bytes per loop, 11th call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 11, |
| 2, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 22); |
| /* Regular test: Text frame, 2 bytes per loop, 12th call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 12, |
| 2, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| "This is the test.", |
| 17, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 23); |
| /* Regular test: Text frame, 1 byte per loop, 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 1, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 1); |
| /* Regular test: Text frame, 1 byte per loop, 22nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 22, |
| 1, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_OK, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 22); |
| /* Regular test: Text frame, 1 byte per loop, 23rd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 23, |
| 1, |
| "\x81\x91\x01\x02\x04\x08" "Ujm{!kw(uja(ugw|/", |
| 23, |
| "This is the test.", |
| 17, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 23); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| mix of fragmented data frames and control frames |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Fragmented text frame mixed with one ping frame (1st call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x89\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented text frame mixed with one ping frame (2nd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x89\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| "This is the test.", |
| 17, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 35); |
| /* Regular test: Fragmented text frame mixed with one close frame (1st call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x88\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 17); |
| /* Fail test: Fragmented text frame mixed with one ping frame (2nd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x88\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 17); |
| /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (1st call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x89\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| "This ", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (2nd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x89\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 17); |
| /* Regular test: Fragmented text frame mixed with one ping frame, the caller wants fragments (3rd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x89\x80\x00\x00\x00\x00" |
| "\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 35, |
| "is the test.", |
| 12, |
| MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 35); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| mix of fragmented data frames and data frames |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: Fragmented text frame mixed with one non-fragmented binary frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x82\x81\x00\x00\x00\x00" |
| "a\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 36, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 11); |
| /* Regular test: Fragmented text frame mixed with one non-fragmented binary frame; the caller wants fragments; 1st call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x82\x81\x00\x00\x00\x00" |
| "a\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 36, |
| "This ", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Fail test: Fragmented text frame mixed with one non-fragmented binary frame; the caller wants fragments; 2nd call */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x82\x81\x00\x00\x00\x00" |
| "a\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 36, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 11); |
| /* Fail test: Fragmented text frame mixed with one fragmented binary frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x02\x81\x00\x00\x00\x00" |
| "a\x80\x8C\x00\x00\x00\x00" "is the test.", |
| 36, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 11); |
| /* Fail test: Fragmented text frame, continue frame, non-fragmented binary frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x00\x8C\x00\x00\x00\x00" |
| "is the test.\x82\x81\x00\x00\x00\x00" "a", |
| 36, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 29); |
| /* Fail test: Fragmented text frame, continue frame, fragmented binary frame */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x01\x85\x00\x00\x00\x00" |
| "This \x00\x8C\x00\x00\x00\x00" |
| "is the test.\x02\x81\x00\x00\x00\x00" "a", |
| 36, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 29); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| multiple data frames |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Text frame, binary frame, text frame (1st call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" |
| "This \x82\x87\x00\x00\x00\x00" |
| "is the \x81\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "This ", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Text frame, binary frame, text frame (2nd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" |
| "This \x82\x87\x00\x00\x00\x00" |
| "is the \x81\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "is the ", |
| 7, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 24); |
| /* Regular test: Text frame, binary frame, text frame (3rd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x81\x85\x00\x00\x00\x00" |
| "This \x82\x87\x00\x00\x00\x00" |
| "is the \x81\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "test.", |
| 5, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 35); |
| /* |
| ------------------------------------------------------------------------------ |
| multiple control frames |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Ping frame, pong frame, close frame (1st call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| "\x89\x85\x00\x00\x00\x00" |
| "This \x8A\x87\x00\x00\x00\x00" |
| "is the \x88\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "This ", |
| 5, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 11); |
| /* Regular test: Ping frame, pong frame, close frame (2nd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 2, |
| 0, |
| "\x89\x85\x00\x00\x00\x00" |
| "This \x8A\x87\x00\x00\x00\x00" |
| "is the \x88\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "is the ", |
| 7, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| 24); |
| /* Regular test: Ping frame, pong frame, close frame (3rd call) */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 3, |
| 0, |
| "\x89\x85\x00\x00\x00\x00" |
| "This \x8A\x87\x00\x00\x00\x00" |
| "is the \x88\x85\x00\x00\x00\x00" "test.", |
| 35, |
| "test.", |
| 5, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| 35); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| generated close frames for errors |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Close frame generated for protocol error */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS |
| | |
| MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR, |
| 0, |
| 1, |
| 0, |
| "\xFF", |
| 1, |
| "\x88\x02\x03\xEA", |
| 4, |
| MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 0); |
| /* Regular test: Close frame generated for UTF-8 sequence error */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS |
| | |
| MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR, |
| 0, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00T\xFFst.", |
| 11, |
| "\x88\x02\x03\xEF", |
| 4, |
| MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 7); |
| /* Regular test: Close frame generated for message size exceeded */ |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS |
| | |
| MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR, |
| 3, |
| 1, |
| 0, |
| "\x81\x85\x00\x00\x00\x00T\xFFst.", |
| 11, |
| "\x88\x02\x03\xF1", |
| 4, |
| MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED, |
| MHD_WEBSOCKET_VALIDITY_INVALID, |
| 2); |
| |
| /* |
| ------------------------------------------------------------------------------ |
| terminating NUL character |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *ws; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0)) |
| { |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| |
| /* Regular test: text frame */ |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) || |
| (5 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("Hello", payload, 5 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: text frame fragment */ |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) || |
| (5 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("Hello", payload, 5 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: binary frame */ |
| ret = MHD_websocket_decode (ws, |
| "\x82\x85\x00\x00\x00\x00" "Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_BINARY_FRAME != ret) || |
| (5 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("Hello", payload, 5 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: binary frame fragment */ |
| ret = MHD_websocket_decode (ws, |
| "\x02\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_BINARY_FRAME != ret) || |
| (5 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("Hello", payload, 5 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| MHD_websocket_stream_free (ws); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Individual decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| { |
| struct MHD_WebSocketStream *ws; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS, |
| 0)) |
| { |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| |
| /* Regular test: text frame fragment (caller wants fragment, 1st call) */ |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo", |
| 17, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT != ret) || |
| (3 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("Hel", payload, 3 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: text frame fragment (caller wants fragment, 2nd call) */ |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" |
| "Hel\x80\x82\x00\x00\x00\x00" "lo" |
| + streambuf_read_len, |
| 17 - streambuf_read_len, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT != ret) || |
| (2 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("lo", payload, 2 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: text frame fragment with broken UTF-8 sequence (caller wants fragment, 1st call) */ |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" |
| "He\xC3\x80\x82\x00\x00\x00\x00" "\xB6o", |
| 17, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT != ret) || |
| (2 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("He", payload, 2 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| /* Regular test: text frame fragment with broken UTF-8 sequence (caller wants fragment, 2nd call) */ |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" |
| "He\xC3\x80\x82\x00\x00\x00\x00" "\xB6o" |
| + streambuf_read_len, |
| 17 - streambuf_read_len, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT != ret) || |
| (3 != payload_len) || |
| (NULL == payload) || |
| (0 != memcmp ("\xC3\xB6o", payload, 3 + 1))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| payload = NULL; |
| } |
| |
| MHD_websocket_stream_free (ws); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Individual decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| |
| /* |
| ------------------------------------------------------------------------------ |
| invalid parameters |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *ws; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0)) |
| { |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| |
| /* Failure test: `ws` is NULL */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (NULL, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Failure test: `buf` is NULL, while `buf_len` != 0 */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| NULL, |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Failure test: `streambuf_read_len` is NULL */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| NULL, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Failure test: `payload` is NULL */ |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| NULL, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != payload_len) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Failure test: `payload_len` is NULL */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != payload) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Regular test: `buf` is NULL and `buf_len` is 0 */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| NULL, |
| 0, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Regular test: `buf` is not NULL and `buf_len` is 0 */ |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 0, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (0 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| |
| MHD_websocket_stream_free (ws); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Parameter decode tests failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *ws; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| |
| /* Failure test: No memory allocation at the start */ |
| disable_alloc = 1; |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (1000 == streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid (ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Failure test: No memory allocation after fragmented frame */ |
| disable_alloc = 0; |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x01\x83\x00\x00\x00\x00" "Hel", |
| 9, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (9 != streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid ( |
| ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| disable_alloc = 1; |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| streambuf_read_len = 1000; |
| ret = MHD_websocket_decode (ws, |
| "\x80\x82\x00\x00\x00\x00" "lo", |
| 8, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (NULL != payload) || |
| (0 != payload_len) || |
| (1000 == streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid ( |
| ws))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| /* Regular test: Success after memory allocation ok again */ |
| /* (streambuf_read_len may not be overwritten for this test) */ |
| disable_alloc = 0; |
| payload = (char *) (uintptr_t) 0xBAADF00D; |
| payload_len = 0x87654321; |
| size_t old_streambuf_read_len = streambuf_read_len; |
| ret = MHD_websocket_decode (ws, |
| "\x80\x82\x00\x00\x00\x00lo" |
| + old_streambuf_read_len, |
| 8 - old_streambuf_read_len, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_TEXT_FRAME != ret) || |
| (NULL == payload) || |
| (5 != payload_len) || |
| (8 != streambuf_read_len + old_streambuf_read_len) || |
| (MHD_WEBSOCKET_VALIDITY_VALID != MHD_websocket_stream_is_valid ( |
| ws)) || |
| (0 != memcmp ("Hello", payload, 5))) |
| { |
| fprintf (stderr, |
| "Decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == payload) |
| { |
| payload = NULL; |
| } |
| if (NULL != payload) |
| { |
| MHD_websocket_free (ws, payload); |
| } |
| |
| MHD_websocket_stream_free (ws); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory decode tests failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| memory leak test, when freeing while decoding |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| disable_alloc = 0; |
| struct MHD_WebSocketStream *ws; |
| size_t streambuf_read_len = 0; |
| char *payload = NULL; |
| size_t payload_len = 0; |
| int ret = 0; |
| |
| /* Regular test: Free while decoding of data frame */ |
| open_allocs = 0; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x81\x85\x00\x00\x00\x00Hel", |
| 9, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (9 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (0 != open_allocs) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u (memory leak detected)\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* Regular test: Free while decoding of control frame */ |
| open_allocs = 0; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x88\x85\x00\x00\x00\x00Hel", |
| 9, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (9 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (0 != open_allocs) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u (memory leak detected)\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* Regular test: Free while decoding of fragmented data frame */ |
| open_allocs = 0; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x01\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (11 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (0 != open_allocs) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u (memory leak detected)\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: Free while decoding of continued fragmented data frame */ |
| open_allocs = 0; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x01\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (11 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_decode (ws, |
| "\x80\x85\x00\x00\x00\x00Hel", |
| 9, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (9 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (0 != open_allocs) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u (memory leak detected)\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: Free while decoding of control frame during fragmented data frame */ |
| open_allocs = 0; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&ws, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | |
| MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| ret = MHD_websocket_decode (ws, |
| "\x01\x85\x00\x00\x00\x00Hello", |
| 11, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (11 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_decode (ws, |
| "\x88\x85\x00\x00\x00\x00Hel", |
| 9, |
| &streambuf_read_len, |
| &payload, |
| &payload_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (0 != payload_len) || |
| (NULL != payload) || |
| (9 != streambuf_read_len) ) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| ret = MHD_websocket_stream_free (ws); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (0 != open_allocs) |
| { |
| fprintf (stderr, |
| "Memory decode test failed in line %u (memory leak detected)\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| else |
| { |
| fprintf (stderr, |
| "Memory test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| { |
| free (buf1); |
| buf1 = NULL; |
| } |
| if (NULL != buf2) |
| { |
| free (buf2); |
| buf2 = NULL; |
| } |
| return failed != 0 ? 0x04 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_encode_text()` |
| */ |
| int |
| test_encodes_text () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *wss; |
| struct MHD_WebSocketStream *wsc; |
| int ret; |
| char *buf1 = NULL, *buf2 = NULL; |
| char *frame = NULL; |
| size_t frame_len = 0; |
| int utf8_step = 0; |
| |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc, |
| MHD_WEBSOCKET_FLAG_CLIENT, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode text tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| return 0x08; |
| } |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0)) |
| { |
| fprintf (stderr, |
| "No encode text tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| return 0x08; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Encoding |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data without UTF-8, we are server */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data without UTF-8, we are client */ |
| ret = MHD_websocket_encode_text (wsc, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (15 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data with UTF-8, we are server */ |
| ret = MHD_websocket_encode_text (wss, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x0B" "bla" "\xC3\xA4" "blabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data with UTF-8, we are client */ |
| ret = MHD_websocket_encode_text (wsc, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (17 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| MHD_WEBSOCKET_STATUS_TEXT_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Some data with NUL characters, we are server */ |
| ret = MHD_websocket_encode_text (wss, |
| "bla" "\0\0\0" "bla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x09" "bla" "\0\0\0" "bla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: Some data with broken UTF-8, we are server */ |
| ret = MHD_websocket_encode_text (wss, |
| "bla" "\xC3" "blabla", |
| 10, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Fragmentation |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data without UTF-8 */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x81\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: First fragment without UTF-8 */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_FIRST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x01\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Middle fragment without UTF-8 */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x00\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment without UTF-8 */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): First fragment with UTF-8 on the edge */ |
| ret = MHD_websocket_encode_text (wss, |
| "blablabl\xC3", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_FIRST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 != utf8_step) || |
| (0 != memcmp (frame, "\x01\x09" "blablabl\xC3", 11))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Last fragment with UTF-8 on the edge */ |
| ret = MHD_websocket_encode_text (wss, |
| "\xA4" "blablabla", |
| 10, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (12 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0A" "\xA4" "blablabla", 12))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: Last fragment with UTF-8 on the edge (here with wrong old utf8_step) */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL; |
| ret = MHD_websocket_encode_text (wss, |
| "\xA4" "blablabla", |
| 10, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF2TAIL_1OF1 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1; |
| ret = MHD_websocket_encode_text (wss, |
| "\xA4" "blablabla", |
| 10, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (12 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0A" "\xA4" "blablabla", 12))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL1_1OF2 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2; |
| ret = MHD_websocket_encode_text (wss, |
| "\xA0\x80" "blablabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0B" "\xA0\x80" "blablabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL2_1OF2 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80\x80" "blablabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0B" "\x80\x80" "blablabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL_1OF2 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80\x80" "blablabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0B" "\x80\x80" "blablabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF3TAIL_2OF2 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80" " blablabla", |
| 11, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0B" "\x80" " blablabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL1_1OF3 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3; |
| ret = MHD_websocket_encode_text (wss, |
| "\x90\x80\x80" "blablabla", |
| 12, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (14 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0C" "\x90\x80\x80" "blablabla", 14))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL2_1OF3 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80\x80\x80" "blablabla", |
| 12, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (14 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0C" "\x80\x80\x80" "blablabla", 14))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_1OF3 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80\x80\x80" "blablabla", |
| 12, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (14 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0C" "\x80\x80\x80" "blablabla", 14))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_2OF3 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80\x80" " blablabla", |
| 12, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (14 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0C" "\x80\x80" " blablabla", 14))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment with UTF-8 on the edge for UTF4TAIL_3OF3 */ |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3; |
| ret = MHD_websocket_encode_text (wss, |
| "\x80" " blablabla", |
| 12, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (14 != frame_len) || |
| (NULL == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x0C" "\x80" " blablabla", 14))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Length checks |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): Text frame without data */ |
| ret = MHD_websocket_encode_text (wss, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Text frame with 1 byte of data */ |
| ret = MHD_websocket_encode_text (wss, |
| "a", |
| 1, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (3 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x01" "a", 3))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Text frame with 125 bytes of data */ |
| ret = MHD_websocket_encode_text (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (127 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x7D" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 127))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Text frame with 126 bytes of data */ |
| ret = MHD_websocket_encode_text (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 126, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (130 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x7E\x00\x7E" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 130))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Text frame with 65535 bytes of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65535, |
| "\x81\x7E\xFF\xFF", |
| 4); |
| ret = MHD_websocket_encode_text (wss, |
| buf2, |
| 65535, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (65535 + 4 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 65535 + 4))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Text frame with 65536 bytes of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65536, |
| "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", |
| 10); |
| ret = MHD_websocket_encode_text (wss, |
| buf2, |
| 65536, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (65536 + 10 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 65536 + 10))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Text frame with 100 MB of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 104857600, |
| "\x81\x7F\x00\x00\x00\x00\x06\x40\x00\x00", |
| 10); |
| ret = MHD_websocket_encode_text (wss, |
| buf2, |
| 104857600, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (104857600 + 10 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 104857600 + 10))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| if (NULL != buf1) |
| { |
| free (buf1); |
| buf1 = NULL; |
| } |
| if (NULL != buf2) |
| { |
| free (buf2); |
| buf2 = NULL; |
| } |
| #ifdef ENABLE_64BIT_TESTS |
| /* Fail test: frame_len is greater than 0x7FFFFFFFFFFFFFFF |
| (this is the maximum allowed payload size) */ |
| frame_len = 0; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| (uint64_t) 0x8000000000000000, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| #endif |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `ws` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (NULL, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `payload_utf8` not passed, but `payload_utf8_len` != 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| NULL, |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `payload_utf8` passed, but `payload_utf8_len` == 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 0, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x81\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `frame` not passed */ |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| NULL, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: `frame_len` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| NULL, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `utf8_step` passed for non-fragmentation |
| (is allowed and `utf8_step` will be filled then) */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = -99; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x81\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `utf8_step` passed for non-fragmentation with invalid UTF-8 |
| (is allowed and `utf8_step` will be filled then) */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = -99; |
| ret = MHD_websocket_encode_text (wss, |
| "ab\xC3", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) || |
| (MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 != utf8_step) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `utf8_step` not passed for fragmentation #1 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_FIRST, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `utf8_step` not passed for fragmentation #2 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `utf8_step` not passed for fragmentation #3 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `utf8_step` passed for fragmentation #1 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = -99; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_FIRST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x01\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `utf8_step` passed for fragmentation #2 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x00\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `utf8_step` passed for fragmentation #3 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = MHD_WEBSOCKET_UTF8STEP_NORMAL; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (MHD_WEBSOCKET_UTF8STEP_NORMAL != utf8_step) || |
| (0 != memcmp (frame, "\x80\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `fragmentation` has an invalid value */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| utf8_step = -99; |
| ret = MHD_websocket_encode_text (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST + 1, |
| &frame, |
| &frame_len, |
| &utf8_step); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) || |
| (-99 != utf8_step) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *wsx; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Fail test: allocation while no memory available */ |
| disable_alloc = 1; |
| ret = MHD_websocket_encode_text (wsx, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| /* Regular test: allocation while memory is available again */ |
| disable_alloc = 0; |
| ret = MHD_websocket_encode_text (wsx, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x81\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode text test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| |
| MHD_websocket_stream_free (wsx); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Couldn't perform memory test for text encoding in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| free (buf1); |
| if (NULL != buf2) |
| free (buf2); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| if (NULL != wss) |
| MHD_websocket_stream_free (wss); |
| |
| return failed != 0 ? 0x08 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_encode_binary()` |
| */ |
| int |
| test_encodes_binary () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *wss; |
| struct MHD_WebSocketStream *wsc; |
| int ret; |
| char *buf1 = NULL, *buf2 = NULL; |
| char *frame = NULL; |
| size_t frame_len = 0; |
| |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc, |
| MHD_WEBSOCKET_FLAG_CLIENT, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode binary tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| return 0x10; |
| } |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0)) |
| { |
| fprintf (stderr, |
| "No encode binary tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| return 0x10; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Encoding |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data, we are server */ |
| ret = MHD_websocket_encode_binary (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data, we are client */ |
| ret = MHD_websocket_encode_binary (wsc, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (15 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_STATUS_BINARY_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Some data with NUL characters, we are server */ |
| ret = MHD_websocket_encode_binary (wss, |
| "bla" "\0\0\0" "bla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x09" "bla" "\0\0\0" "bla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data which looks like broken UTF-8, we are server */ |
| ret = MHD_websocket_encode_binary (wss, |
| "bla" "\xC3" "blabla", |
| 10, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (12 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x0A" "bla" "\xC3" "blabla", 12))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Fragmentation |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data */ |
| ret = MHD_websocket_encode_binary (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: First fragment */ |
| ret = MHD_websocket_encode_binary (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_FIRST, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x02\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Middle fragment */ |
| ret = MHD_websocket_encode_binary (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x00\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Last fragment */ |
| ret = MHD_websocket_encode_binary (wss, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x80\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Length checks |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): Binary frame without data */ |
| ret = MHD_websocket_encode_binary (wss, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Binary frame with 1 byte of data */ |
| ret = MHD_websocket_encode_binary (wss, |
| "a", |
| 1, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (3 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x01" "a", 3))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Binary frame with 125 bytes of data */ |
| ret = MHD_websocket_encode_binary (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (127 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x7D" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 127))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Binary frame with 126 bytes of data */ |
| ret = MHD_websocket_encode_binary (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 126, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (130 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x7E\x00\x7E" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 130))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Binary frame with 65535 bytes of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65535, |
| "\x82\x7E\xFF\xFF", |
| 4); |
| ret = MHD_websocket_encode_binary (wss, |
| buf2, |
| 65535, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (65535 + 4 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 65535 + 4))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Binary frame with 65536 bytes of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 65536, |
| "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00", |
| 10); |
| ret = MHD_websocket_encode_binary (wss, |
| buf2, |
| 65536, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (65536 + 10 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 65536 + 10))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Binary frame with 100 MB of data */ |
| allocate_length_test_data (&buf1, |
| &buf2, |
| 104857600, |
| "\x82\x7F\x00\x00\x00\x00\x06\x40\x00\x00", |
| 10); |
| ret = MHD_websocket_encode_binary (wss, |
| buf2, |
| 104857600, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (104857600 + 10 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, buf1, 104857600 + 10))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| if (NULL != buf1) |
| { |
| free (buf1); |
| buf1 = NULL; |
| } |
| if (NULL != buf2) |
| { |
| free (buf2); |
| buf2 = NULL; |
| } |
| #ifdef ENABLE_64BIT_TESTS |
| /* Fail test: `frame_len` is greater than 0x7FFFFFFFFFFFFFFF |
| (this is the maximum allowed payload size) */ |
| frame_len = 0; |
| ret = MHD_websocket_encode_binary (wss, |
| "abc", |
| (uint64_t) 0x8000000000000000, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| #endif |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `ws` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_binary (NULL, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `payload` not passed, but `payload_len` != 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_binary (wss, |
| NULL, |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `payload` passed, but `payload_len` == 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_binary (wss, |
| "abc", |
| 0, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x82\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `frame` not passed */ |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_binary (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| NULL, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: `frame_len` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| ret = MHD_websocket_encode_binary (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `fragmentation` has an invalid value */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_binary (wss, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_LAST + 1, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *wsx; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Fail test: allocation while no memory available */ |
| disable_alloc = 1; |
| ret = MHD_websocket_encode_binary (wsx, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| /* Regular test: allocation while memory is available again */ |
| disable_alloc = 0; |
| ret = MHD_websocket_encode_binary (wsx, |
| "abc", |
| 3, |
| MHD_WEBSOCKET_FRAGMENTATION_NONE, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x82\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode binary test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| |
| MHD_websocket_stream_free (wsx); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Couldn't perform memory test for binary encoding in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| free (buf1); |
| if (NULL != buf2) |
| free (buf2); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| if (NULL != wss) |
| MHD_websocket_stream_free (wss); |
| |
| return failed != 0 ? 0x10 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_encode_close()` |
| */ |
| int |
| test_encodes_close () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *wss; |
| struct MHD_WebSocketStream *wsc; |
| int ret; |
| char *buf1 = NULL, *buf2 = NULL; |
| char *frame = NULL; |
| size_t frame_len = 0; |
| |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc, |
| MHD_WEBSOCKET_FLAG_CLIENT, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode close tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| return 0x10; |
| } |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wss, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode close tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| return 0x10; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Encoding |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data, we are server */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x0B\x03\xE8" "blablabla", 13))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data, we are client */ |
| ret = MHD_websocket_encode_close (wsc, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (17 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "\x03\xE8" "blablabla", |
| 11, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Close reason without text, we are server */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (4 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x02\x03\xE8", 4))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Close reason without text, we are client */ |
| ret = MHD_websocket_encode_close (wsc, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (8 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "\x03\xE8", |
| 2, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Close without reason, we are server */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_NO_REASON, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Close without reason, we are client */ |
| ret = MHD_websocket_encode_close (wsc, |
| MHD_WEBSOCKET_CLOSEREASON_NO_REASON, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (6 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Close with UTF-8 sequence in reason, we are client */ |
| ret = MHD_websocket_encode_close (wsc, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (19 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "\x03\xE8" "bla" "\xC3\xA4" "blabla", |
| 13, |
| MHD_WEBSOCKET_STATUS_CLOSE_FRAME, |
| MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Close reason with NUL characters, we are server */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_GOING_AWAY, |
| "bla" "\0\0\0" "bla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (13 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x0B\x03\xE9" "bla" "\0\0\0" "bla", 13))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: Some data with broken UTF-8, we are server */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "bla" "\xC3" "blabla", |
| 10, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Length checks |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): Close frame without payload */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_NO_REASON, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Close frame only reason code */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (4 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x02\x03\xE8", 4))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Close frame with 1 bytes of reason text */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "a", |
| 1, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x03\x03\xE8" "a", 5))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Close frame with 123 bytes of reason text */ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456", |
| 123, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (127 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x7D\x03\xE8" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456", |
| 127))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (fail): Close frame with 124 bytes of reason text*/ |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567", |
| 124, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `ws` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (NULL, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `payload` not passed, but `payload_len` != 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| NULL, |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `payload` passed, but `payload_len` == 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (4 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x88\x02\x03\xE8", 4))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `frame` not passed */ |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 3, |
| NULL, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: `frame_len` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 3, |
| &frame, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: no reason code passed, but reason text */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| MHD_WEBSOCKET_CLOSEREASON_NO_REASON, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (fail): Invalid reason code */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| 1, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (fail): Invalid reason code */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| 999, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Custom reason code */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_close (wss, |
| 2000, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (7 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x88\x05\x07\xD0" "abc", 7))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *wsx; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Fail test: allocation while no memory available */ |
| disable_alloc = 1; |
| ret = MHD_websocket_encode_close (wsx, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| /* Regular test: allocation while memory is available again */ |
| disable_alloc = 0; |
| ret = MHD_websocket_encode_close (wsx, |
| MHD_WEBSOCKET_CLOSEREASON_REGULAR, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (7 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x88\x05\x03\xE8" "abc", 7))) |
| { |
| fprintf (stderr, |
| "Encode close test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| |
| MHD_websocket_stream_free (wsx); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Couldn't perform memory test for close encoding in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| free (buf1); |
| if (NULL != buf2) |
| free (buf2); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| if (NULL != wss) |
| MHD_websocket_stream_free (wss); |
| |
| return failed != 0 ? 0x20 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_encode_ping()` |
| */ |
| int |
| test_encodes_ping () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *wss; |
| struct MHD_WebSocketStream *wsc; |
| int ret; |
| char *buf1 = NULL, *buf2 = NULL; |
| char *frame = NULL; |
| size_t frame_len = 0; |
| |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc, |
| MHD_WEBSOCKET_FLAG_CLIENT, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode ping tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| return 0x10; |
| } |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0)) |
| { |
| fprintf (stderr, |
| "No encode ping tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| return 0x10; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Encoding |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data, we are server */ |
| ret = MHD_websocket_encode_ping (wss, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data, we are client */ |
| ret = MHD_websocket_encode_ping (wsc, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (15 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Ping without payload, we are server */ |
| ret = MHD_websocket_encode_ping (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Ping without payload, we are client */ |
| ret = MHD_websocket_encode_ping (wsc, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (6 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Ping with something like UTF-8 sequence in payload, we are client */ |
| ret = MHD_websocket_encode_ping (wsc, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (17 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| MHD_WEBSOCKET_STATUS_PING_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Ping payload with NUL characters, we are server */ |
| ret = MHD_websocket_encode_ping (wss, |
| "bla" "\0\0\0" "bla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x09" "bla" "\0\0\0" "bla", 11))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Ping payload with with something which looks like broken UTF-8, we are server */ |
| ret = MHD_websocket_encode_ping (wss, |
| "bla" "\xC3" "blabla", |
| 10, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (12 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x0A" "bla" "\xC3" "blabla", 12))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Length checks |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): Ping frame without payload */ |
| ret = MHD_websocket_encode_ping (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Ping frame with one byte of payload */ |
| ret = MHD_websocket_encode_ping (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Ping frame with 125 bytes of payload */ |
| ret = MHD_websocket_encode_ping (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (127 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x7D" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 127))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (fail): Ping frame with 126 bytes of payload */ |
| ret = MHD_websocket_encode_ping (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 126, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `ws` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_ping (NULL, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `payload` not passed, but `payload_len` != 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_ping (wss, |
| NULL, |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `payload` passed, but `payload_len` == 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_ping (wss, |
| "abc", |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x89\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `frame` not passed */ |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_ping (wss, |
| "abc", |
| 3, |
| NULL, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: `frame_len` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| ret = MHD_websocket_encode_ping (wss, |
| "abc", |
| 3, |
| &frame, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *wsx; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Fail test: allocation while no memory available */ |
| disable_alloc = 1; |
| ret = MHD_websocket_encode_ping (wsx, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| /* Regular test: allocation while memory is available again */ |
| disable_alloc = 0; |
| ret = MHD_websocket_encode_ping (wsx, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x89\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode ping test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| |
| MHD_websocket_stream_free (wsx); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Couldn't perform memory test for ping encoding in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| free (buf1); |
| if (NULL != buf2) |
| free (buf2); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| if (NULL != wss) |
| MHD_websocket_stream_free (wss); |
| |
| return failed != 0 ? 0x40 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_encode_pong()` |
| */ |
| int |
| test_encodes_pong () |
| { |
| int failed = 0; |
| struct MHD_WebSocketStream *wss; |
| struct MHD_WebSocketStream *wsc; |
| int ret; |
| char *buf1 = NULL, *buf2 = NULL; |
| char *frame = NULL; |
| size_t frame_len = 0; |
| |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init2 (&wsc, |
| MHD_WEBSOCKET_FLAG_CLIENT, |
| 0, |
| malloc, |
| realloc, |
| free, |
| NULL, |
| test_rng)) |
| { |
| fprintf (stderr, |
| "No encode pong tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| return 0x10; |
| } |
| if (MHD_WEBSOCKET_STATUS_OK != MHD_websocket_stream_init (&wss, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0)) |
| { |
| fprintf (stderr, |
| "No encode pong tests possible due to failed stream init in line %u\n", |
| (unsigned int) __LINE__); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| return 0x10; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Encoding |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Some data, we are server */ |
| ret = MHD_websocket_encode_pong (wss, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x09" "blablabla", 11))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Some data, we are client */ |
| ret = MHD_websocket_encode_pong (wsc, |
| "blablabla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (15 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "blablabla", |
| 9, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Pong without payload, we are server */ |
| ret = MHD_websocket_encode_pong (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Pong without payload, we are client */ |
| ret = MHD_websocket_encode_pong (wsc, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (6 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| NULL, |
| 0, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Regular test: Pong with something like UTF-8 sequence in payload, we are client */ |
| ret = MHD_websocket_encode_pong (wsc, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (17 != frame_len) || |
| (NULL == frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| else |
| { |
| failed += test_decode_single (__LINE__, |
| MHD_WEBSOCKET_FLAG_SERVER |
| | MHD_WEBSOCKET_FLAG_NO_FRAGMENTS, |
| 0, |
| 1, |
| 0, |
| frame, |
| frame_len, |
| "bla" "\xC3\xA4" "blabla", |
| 11, |
| MHD_WEBSOCKET_STATUS_PONG_FRAME, |
| MHD_WEBSOCKET_VALIDITY_VALID, |
| frame_len); |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsc, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Pong payload with NUL characters, we are server */ |
| ret = MHD_websocket_encode_pong (wss, |
| "bla" "\0\0\0" "bla", |
| 9, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (11 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x09" "bla" "\0\0\0" "bla", 11))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: Pong payload with with something which looks like broken UTF-8, we are server */ |
| ret = MHD_websocket_encode_pong (wss, |
| "bla" "\xC3" "blabla", |
| 10, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (12 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x0A" "bla" "\xC3" "blabla", 12))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Length checks |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): Pong frame without payload */ |
| ret = MHD_websocket_encode_pong (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Pong frame with one byte of payload */ |
| ret = MHD_websocket_encode_pong (wss, |
| NULL, |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (success): Pong frame with 125 bytes of payload */ |
| ret = MHD_websocket_encode_pong (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 125, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (127 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x7D" |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678", |
| 127))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Edge test (fail): Pong frame with 126 bytes of payload */ |
| ret = MHD_websocket_encode_pong (wss, |
| "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
| 126, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `ws` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_pong (NULL, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `payload` not passed, but `payload_len` != 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_pong (wss, |
| NULL, |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Regular test: `payload` passed, but `payload_len` == 0 */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_pong (wss, |
| "abc", |
| 0, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (2 != frame_len) || |
| (NULL == frame) || |
| (((char *) (uintptr_t) 0xBAADF00D) == frame) || |
| (0 != memcmp (frame, "\x8A\x00", 2))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| /* Fail test: `frame` not passed */ |
| frame_len = 0x87654321; |
| ret = MHD_websocket_encode_pong (wss, |
| "abc", |
| 3, |
| NULL, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (0 != frame_len) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: `frame_len` not passed */ |
| frame = (char *) (uintptr_t) 0xBAADF00D; |
| ret = MHD_websocket_encode_pong (wss, |
| "abc", |
| 3, |
| &frame, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (((char *) (uintptr_t) 0xBAADF00D) == frame) |
| { |
| frame = NULL; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wss, frame); |
| frame = NULL; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| validity after temporary out-of-memory |
| ------------------------------------------------------------------------------ |
| */ |
| { |
| struct MHD_WebSocketStream *wsx; |
| if (MHD_WEBSOCKET_STATUS_OK == MHD_websocket_stream_init2 (&wsx, |
| MHD_WEBSOCKET_FLAG_SERVER, |
| 0, |
| test_malloc, |
| test_realloc, |
| test_free, |
| NULL, |
| NULL)) |
| { |
| /* Fail test: allocation while no memory available */ |
| disable_alloc = 1; |
| ret = MHD_websocket_encode_pong (wsx, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_MEMORY_ERROR != ret) || |
| (0 != frame_len) || |
| (NULL != frame) ) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| /* Regular test: allocation while memory is available again */ |
| disable_alloc = 0; |
| ret = MHD_websocket_encode_pong (wsx, |
| "abc", |
| 3, |
| &frame, |
| &frame_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (5 != frame_len) || |
| (NULL == frame) || |
| (0 != memcmp (frame, "\x8A\x03" "abc", 5))) |
| { |
| fprintf (stderr, |
| "Encode pong test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| if (NULL != frame) |
| { |
| MHD_websocket_free (wsx, frame); |
| frame = NULL; |
| } |
| |
| MHD_websocket_stream_free (wsx); |
| } |
| else |
| { |
| fprintf (stderr, |
| "Couldn't perform memory test for pong encoding in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| } |
| |
| if (NULL != buf1) |
| free (buf1); |
| if (NULL != buf2) |
| free (buf2); |
| if (NULL != wsc) |
| MHD_websocket_stream_free (wsc); |
| if (NULL != wss) |
| MHD_websocket_stream_free (wss); |
| |
| return failed != 0 ? 0x80 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_split_close_reason()` |
| */ |
| int |
| test_split_close_reason () |
| { |
| int failed = 0; |
| const char *payload; |
| unsigned short reason_code; |
| const char *reason_utf8; |
| size_t reason_utf8_len; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Normal splits |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Reason code + Reason text */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = "\x03\xE8" "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 5, |
| &reason_code, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) || |
| (3 != reason_utf8_len) || |
| (payload + 2 != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: Reason code */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = "\x03\xE8"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 2, |
| &reason_code, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) || |
| (0 != reason_utf8_len) || |
| (NULL != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: No payload */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = NULL; |
| ret = MHD_websocket_split_close_reason (payload, |
| 0, |
| &reason_code, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) || |
| (0 != reason_utf8_len) || |
| (NULL != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: `payload` is not NULL given, but `payload_len` == 0 */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 0, |
| &reason_code, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) || |
| (0 != reason_utf8_len) || |
| (NULL != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Wrong parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: `payload` not passed, but `payload_len` != 0 */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = NULL; |
| ret = MHD_websocket_split_close_reason (payload, |
| 3, |
| &reason_code, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_PARAMETER_ERROR != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_NO_REASON != reason_code) || |
| (0 != reason_utf8_len) || |
| (NULL != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: `reason_code` not passed */ |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| reason_utf8_len = 12345; |
| payload = "\x03\xE8" "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 5, |
| NULL, |
| &reason_utf8, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (3 != reason_utf8_len) || |
| (payload + 2 != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: `reason_utf8` not passed */ |
| reason_code = 9999; |
| reason_utf8_len = 12345; |
| payload = "\x03\xE8" "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 5, |
| &reason_code, |
| NULL, |
| &reason_utf8_len); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) || |
| (3 != reason_utf8_len) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: `reason_utf8_len` not passed */ |
| reason_code = 9999; |
| reason_utf8 = (const char *) (intptr_t) 0xBAADF00D; |
| payload = "\x03\xE8" "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 5, |
| &reason_code, |
| &reason_utf8, |
| NULL); |
| if ((MHD_WEBSOCKET_STATUS_OK != ret) || |
| (MHD_WEBSOCKET_CLOSEREASON_REGULAR != reason_code) || |
| (payload + 2 != reason_utf8) ) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: `reason_code`, `reason_utf8` and `reason_utf8_len` not passed */ |
| /* (this is not prohibited, although it doesn't really make sense) */ |
| payload = "\x03\xE8" "abc"; |
| ret = MHD_websocket_split_close_reason (payload, |
| 5, |
| NULL, |
| NULL, |
| NULL); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "split close reason test failed in line %u\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x100 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_check_http_version()` |
| */ |
| int |
| test_check_http_version () |
| { |
| int failed = 0; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Version check with valid HTTP version syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: HTTP/1.1 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.1"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: HTTP/1.2 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.2"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: HTTP/1.10 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.10"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: HTTP/2.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/2.0"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: HTTP/3.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/3.0"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: HTTP/1.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.0"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: HTTP/0.9 */ |
| ret = MHD_websocket_check_http_version ("HTTP/0.9"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Version check edge cases |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): HTTP/123.45 */ |
| ret = MHD_websocket_check_http_version ("HTTP/123.45"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/1.45 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.45"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/01.1 */ |
| ret = MHD_websocket_check_http_version ("HTTP/01.1"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/0001.1 */ |
| ret = MHD_websocket_check_http_version ("HTTP/0001.1"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/1.01 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.01"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/1.0001 */ |
| ret = MHD_websocket_check_http_version ("HTTP/1.0001"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/0001.0001 */ |
| ret = MHD_websocket_check_http_version ("HTTP/0001.0001"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/2.000 */ |
| ret = MHD_websocket_check_http_version ("HTTP/2.000"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): HTTP/0.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/0.0"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): HTTP/00.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/00.0"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): HTTP/00.0 */ |
| ret = MHD_websocket_check_http_version ("HTTP/0.00"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Invalid version syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: (empty string) */ |
| ret = MHD_websocket_check_http_version (""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: http/1.1 */ |
| ret = MHD_websocket_check_http_version ("http/1.1"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: "HTTP / 1.1" */ |
| ret = MHD_websocket_check_http_version ("HTTP / 1.1"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: NULL as version */ |
| ret = MHD_websocket_check_http_version (NULL); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_http_version test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x200 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_check_connection_header()` |
| */ |
| int |
| test_check_connection_header () |
| { |
| int failed = 0; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Check with valid Connection header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: Upgrade */ |
| ret = MHD_websocket_check_connection_header ("Upgrade"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Regular test: keep-alive, Upgrade */ |
| ret = MHD_websocket_check_connection_header ("keep-alive, Upgrade"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: keep-alive */ |
| ret = MHD_websocket_check_connection_header ("keep-alive"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: close */ |
| ret = MHD_websocket_check_connection_header ("close"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Connection check edge cases |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): keep-alive,Upgrade */ |
| ret = MHD_websocket_check_connection_header ("keep-alive,Upgrade"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Upgrade, keep-alive */ |
| ret = MHD_websocket_check_connection_header ("Upgrade, keep-alive"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Upgrade,keep-alive */ |
| ret = MHD_websocket_check_connection_header ("Upgrade,keep-alive"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Transfer-Encoding,Upgrade,keep-alive */ |
| ret = MHD_websocket_check_connection_header ( |
| "Transfer-Encoding,Upgrade,keep-alive"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Transfer-Encoding , Upgrade , keep-alive */ |
| ret = MHD_websocket_check_connection_header ( |
| "Transfer-Encoding , Upgrade , keep-alive"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): upgrade */ |
| ret = MHD_websocket_check_connection_header ("upgrade"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): UPGRADE */ |
| ret = MHD_websocket_check_connection_header ("UPGRADE"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): All allowed token characters, then upgrade token */ |
| ret = MHD_websocket_check_connection_header ( |
| "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,Upgrade"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Different, allowed whitespaces */ |
| ret = MHD_websocket_check_connection_header (" \tUpgrade \t"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_connection_header ("\rUpgrade"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_connection_header ("\nUpgrade"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_connection_header ("\vUpgrade"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_connection_header ("\fUpgrade"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Invalid header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: (empty string) */ |
| ret = MHD_websocket_check_connection_header (""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: (Disallowed) multiple word token with the term "Upgrade" in it */ |
| ret = MHD_websocket_check_connection_header ("Upgrade or Downgrade"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: Invalid characters */ |
| ret = MHD_websocket_check_connection_header ("\"Upgrade\""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: NULL as connection */ |
| ret = MHD_websocket_check_connection_header (NULL); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_connection_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x400 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_check_upgrade_header()` |
| */ |
| int |
| test_check_upgrade_header () |
| { |
| int failed = 0; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Check with valid Upgrade header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: websocket */ |
| ret = MHD_websocket_check_upgrade_header ("websocket"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: HTTP/2.0 */ |
| ret = MHD_websocket_check_upgrade_header ("HTTP/2.0"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Upgrade check edge cases |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (success): websocket,HTTP/2.0 */ |
| ret = MHD_websocket_check_upgrade_header ("websocket,HTTP/2.0"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): websocket ,HTTP/2.0 */ |
| ret = MHD_websocket_check_upgrade_header (" websocket ,HTTP/2.0"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): HTTP/2.0, websocket */ |
| ret = MHD_websocket_check_upgrade_header ("HTTP/2.0, websocket "); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): websocket/13 */ |
| ret = MHD_websocket_check_upgrade_header ("websocket/13"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): WeBsOcKeT */ |
| ret = MHD_websocket_check_upgrade_header ("WeBsOcKeT"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): WEBSOCKET */ |
| ret = MHD_websocket_check_upgrade_header ("WEBSOCKET"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): All allowed token characters plus /, then websocket keyword */ |
| ret = MHD_websocket_check_upgrade_header ( |
| "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/,websocket"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (success): Different, allowed whitespaces */ |
| ret = MHD_websocket_check_upgrade_header (" \twebsocket \t"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_upgrade_header ("\rwebsocket"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_upgrade_header ("\nwebsocket"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_upgrade_header ("\vwebsocket"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): Different, disallowed whitespaces */ |
| ret = MHD_websocket_check_upgrade_header ("\fwebsocket"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Invalid header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: (empty string) */ |
| ret = MHD_websocket_check_upgrade_header (""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: (Disallowed) multiple word token with the term "websocket" in it */ |
| ret = MHD_websocket_check_upgrade_header ("websocket or something"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: Invalid characters */ |
| ret = MHD_websocket_check_upgrade_header ("\"websocket\""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: NULL as upgrade */ |
| ret = MHD_websocket_check_upgrade_header (NULL); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_upgrade_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x800 : 0x00; |
| } |
| |
| |
| /** |
| * Test procedure for `MHD_websocket_check_version_header()` |
| */ |
| int |
| test_check_version_header () |
| { |
| int failed = 0; |
| int ret; |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Check with valid Upgrade header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Regular test: 13 */ |
| ret = MHD_websocket_check_version_header ("13"); |
| if (MHD_WEBSOCKET_STATUS_OK != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Version check edge cases |
| ------------------------------------------------------------------------------ |
| */ |
| /* Edge test (fail): 14 */ |
| ret = MHD_websocket_check_version_header ("14"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): 12 */ |
| ret = MHD_websocket_check_version_header ("12"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): 0 */ |
| ret = MHD_websocket_check_version_header ("1"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): 1 */ |
| ret = MHD_websocket_check_version_header ("1"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): 130 */ |
| ret = MHD_websocket_check_version_header ("130"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Edge test (fail): " 13" */ |
| ret = MHD_websocket_check_version_header (" 13"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Invalid header syntax |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: (empty string) */ |
| ret = MHD_websocket_check_version_header (""); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| /* Fail test: Invalid characters */ |
| ret = MHD_websocket_check_version_header ("abc"); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| Missing parameters |
| ------------------------------------------------------------------------------ |
| */ |
| /* Fail test: NULL as version */ |
| ret = MHD_websocket_check_version_header (NULL); |
| if (MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER != ret) |
| { |
| fprintf (stderr, |
| "check_version_header test failed in line %u.\n", |
| (unsigned int) __LINE__); |
| ++failed; |
| } |
| |
| return failed != 0 ? 0x1000 : 0x00; |
| } |
| |
| |
| int |
| main (int argc, char *const *argv) |
| { |
| unsigned int errorCount = 0; |
| (void) argc; (void) argv; /* Unused. Silent compiler warning. */ |
| |
| /* seed random number generator */ |
| srand ((unsigned long) time (NULL)); |
| |
| /* perform tests */ |
| errorCount += test_inits (); |
| errorCount += test_accept (); |
| errorCount += test_decodes (); |
| errorCount += test_encodes_text (); |
| errorCount += test_encodes_binary (); |
| errorCount += test_encodes_close (); |
| errorCount += test_encodes_ping (); |
| errorCount += test_encodes_pong (); |
| errorCount += test_split_close_reason (); |
| errorCount += test_check_http_version (); |
| errorCount += test_check_connection_header (); |
| errorCount += test_check_upgrade_header (); |
| errorCount += test_check_version_header (); |
| |
| /* output result */ |
| if (errorCount != 0) |
| fprintf (stderr, "Error (code: %u)\n", errorCount); |
| |
| return errorCount != 0; /* 0 == pass */ |
| } |