add generation wstest to cmake

add wstestdata.c, because the python data generation script has too many
dependencies

remove some redundance from jpeg test creation

add support for decoding close messages
pull/3/head
Andreas Weigel 8 years ago committed by Christian Beier
parent f19d6ee225
commit 826e0f9e39
No known key found for this signature in database
GPG Key ID: 421BB3B45C6067F8

2
.gitignore vendored

@ -67,8 +67,6 @@ test/copyrecttest
test/cursortest test/cursortest
test/encodingstest test/encodingstest
test/wstest test/wstest
test/wsmaketestframe.py
test/wstestdata.in
/test/tjbench /test/tjbench
/test/tjunittest /test/tjunittest
vncterm/LinuxVNC vncterm/LinuxVNC

@ -49,7 +49,6 @@ option(WITH_IPv6 "Enable IPv6 Support" ON)
option(WITH_WEBSOCKETS "Build with websockets support" ON) option(WITH_WEBSOCKETS "Build with websockets support" ON)
if(WITH_ZLIB) if(WITH_ZLIB)
find_package(ZLIB) find_package(ZLIB)
endif(WITH_ZLIB) endif(WITH_ZLIB)
@ -387,6 +386,7 @@ if(LIBVNCSERVER_WITH_WEBSOCKETS)
set(LIBVNCSERVER_SOURCES set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES} ${LIBVNCSERVER_SOURCES}
${LIBVNCSERVER_DIR}/websockets.c ${LIBVNCSERVER_DIR}/websockets.c
${LIBVNCSERVER_DIR}/ws_decode.c
${WSSRCS} ${WSSRCS}
) )
endif(LIBVNCSERVER_WITH_WEBSOCKETS) endif(LIBVNCSERVER_WITH_WEBSOCKETS)
@ -500,11 +500,9 @@ foreach(e ${LIBVNCCLIENT_EXAMPLES})
target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL_LIBRARY} ${FFMPEG_LIBRARIES}) target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL_LIBRARY} ${FFMPEG_LIBRARIES})
endforeach(e ${LIBVNCCLIENT_EXAMPLES}) endforeach(e ${LIBVNCCLIENT_EXAMPLES})
# #
# them tests # them tests
# #
if(UNIX) if(UNIX)
set(ADDITIONAL_TEST_LIBS m) set(ADDITIONAL_TEST_LIBS m)
endif(UNIX) endif(UNIX)
@ -512,18 +510,41 @@ endif(UNIX)
set(SIMPLETESTS set(SIMPLETESTS
cargstest cargstest
copyrecttest copyrecttest
wstest
) )
if(CMAKE_USE_PTHREADS_INIT) add_test(NAME cargs COMMAND test_cargstest)
set(SIMPLETESTS add_test(NAME websockets_decode COMMAND test_wstest)
${SIMPLETESTS}
encodingstest if(CMAKE_USE_PTHREADS_INI)
list(APPEND SIMPLETESTS encodingstest)
endif(CMAKE_USE_PTHREADS_INI)
if(FOUND_LIBJPEG_TURBO)
list(APPEND SIMPLETESTS tjunittest tjbench)
set(tjunittest_add_src
${TESTS_DIR}/tjutil.c
${TESTS_DIR}/tjutil.h
${COMMON_DIR}/turbojpeg.c
${COMMON_DIR}/turbojpeg.h
) )
endif(CMAKE_USE_PTHREADS_INIT)
set(tjbench_add_src
${TESTS_DIR}/tjbench.c
${TESTS_DIR}/tjutil.c
${TESTS_DIR}/tjutil.h
${TESTS_DIR}/bmp.c
${TESTS_DIR}/bmp.h
${COMMON_DIR}/turbojpeg.c
${COMMON_DIR}/turbojpeg.h
)
add_test(NAME turbojpeg COMMAND test_tjunittest)
endif(FOUND_LIBJPEG_TURBO)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test)
foreach(t ${SIMPLETESTS}) foreach(t ${SIMPLETESTS})
add_executable(test_${t} ${TESTS_DIR}/${t}.c) add_executable(test_${t} ${TESTS_DIR}/${t}.c ${${t}_add_src})
set_target_properties(test_${t} PROPERTIES OUTPUT_NAME ${t}) set_target_properties(test_${t} PROPERTIES OUTPUT_NAME ${t})
set_target_properties(test_${t} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) set_target_properties(test_${t} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test)
target_link_libraries(test_${t} vncserver vncclient ${ADDITIONAL_TEST_LIBS}) target_link_libraries(test_${t} vncserver vncclient ${ADDITIONAL_TEST_LIBS})
@ -561,8 +582,6 @@ if(FOUND_LIBJPEG_TURBO)
add_test(NAME turbojpeg COMMAND test_tjunittest) add_test(NAME turbojpeg COMMAND test_tjunittest)
endif(FOUND_LIBJPEG_TURBO) endif(FOUND_LIBJPEG_TURBO)
# #
# this gets the libraries needed by TARGET in "-libx -liby ..." form # this gets the libraries needed by TARGET in "-libx -liby ..." form
# #

@ -85,11 +85,12 @@ hybiReturnData(char *dst, int len, ws_ctx_t *wsctx, int *nWritten)
* *
* @param[in] cl client ptr with ptr to raw socket and ws_ctx_t ptr * @param[in] cl client ptr with ptr to raw socket and ws_ctx_t ptr
* @param[out] sockRet emulated recv return value * @param[out] sockRet emulated recv return value
* @param[out] nPayload number of payload bytes already read
* @return next hybi decoding state; WS_HYBI_STATE_HEADER_PENDING indicates * @return next hybi decoding state; WS_HYBI_STATE_HEADER_PENDING indicates
* that the header was not received completely. * that the header was not received completely.
*/ */
static int static int
hybiReadHeader(ws_ctx_t *wsctx, int *sockRet) hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
{ {
int ret; int ret;
char *headerDst = wsctx->codeBufDecode + wsctx->nReadRaw; char *headerDst = wsctx->codeBufDecode + wsctx->nReadRaw;
@ -184,7 +185,8 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet)
/* set payload pointer just after header */ /* set payload pointer just after header */
wsctx->readPos = (unsigned char *)(wsctx->codeBufDecode + wsctx->header.headerLen); wsctx->readPos = (unsigned char *)(wsctx->codeBufDecode + wsctx->header.headerLen);
rfbLog("header complete: state=%d flen=%d writeTo=%p\n", wsctx->hybiDecodeState, wsctx->nToRead, wsctx->writePos); *nPayload = wsctx->nReadRaw - wsctx->header.headerLen;
rfbLog("header complete: state=%d flen=%d writeTo=%p nPayload=%d\n", wsctx->hybiDecodeState, wsctx->nToRead, wsctx->writePos, *nPayload);
return WS_HYBI_STATE_DATA_NEEDED; return WS_HYBI_STATE_DATA_NEEDED;
} }
@ -217,21 +219,24 @@ hybiPayloadStart(ws_ctx_t *wsctx)
* - execute return data routine * - execute return data routine
* *
* Sets errno corresponding to what it gets from the underlying * Sets errno corresponding to what it gets from the underlying
* socket or EIO if some internal sanity check fails. * socket or EPROTO if some invalid data is in the received frame
* or ECONNRESET if a close reason + message is received. EIO is used if
* an internal sanity check fails.
* *
* @param[in] cl client ptr with raw socket reference * @param[in] cl client ptr with raw socket reference
* @param[out] dst destination buffer * @param[out] dst destination buffer
* @param[in] len size of destination buffer * @param[in] len size of destination buffer
* @param[out] sockRet emulated recv return value * @param[out] sockRet emulated recv return value
* @param[in] nInBuf number of undecoded bytes before writePos from header read
* @return next hybi decode state * @return next hybi decode state
*/ */
static int static int
hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet) hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet, int nInBuf)
{ {
int n; int n;
int i; int i;
int toReturn; int toReturn; /* number of data bytes to return */
int toDecode; int toDecode; /* number of bytes to decode starting at wsctx->writePos */
int bufsize; int bufsize;
int nextRead; int nextRead;
unsigned char *data; unsigned char *data;
@ -253,7 +258,6 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
if (wsctx->nReadRaw < wsctx->nToRead) { if (wsctx->nReadRaw < wsctx->nToRead) {
/* decode more data */ /* decode more data */
//if (-1 == (n = ws_read(cl, wsctx->writePos, nextRead))) {
if (-1 == (n = wsctx->ctxInfo.readFunc(wsctx->ctxInfo.ctxPtr, wsctx->writePos, nextRead))) { if (-1 == (n = wsctx->ctxInfo.readFunc(wsctx->ctxInfo.ctxPtr, wsctx->writePos, nextRead))) {
int olderrno = errno; int olderrno = errno;
rfbErr("%s: read; %s", __func__, strerror(errno)); rfbErr("%s: read; %s", __func__, strerror(errno));
@ -283,7 +287,9 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
} }
} }
toDecode = wsctx->writePos - hybiPayloadStart(wsctx); /* number of not yet unmasked payload bytes: what we read here + what was
* carried over + what was read with the header */
toDecode = n + wsctx->carrylen + nInBuf;
rfbLog("toDecode=%d from n=%d carrylen=%d headerLen=%d\n", toDecode, n, wsctx->carrylen, wsctx->header.headerLen); rfbLog("toDecode=%d from n=%d carrylen=%d headerLen=%d\n", toDecode, n, wsctx->carrylen, wsctx->header.headerLen);
if (toDecode < 0) { if (toDecode < 0) {
rfbErr("%s: internal error; negative number of bytes to decode: %d", __func__, toDecode); rfbErr("%s: internal error; negative number of bytes to decode: %d", __func__, toDecode);
@ -294,7 +300,7 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
/* for a possible base64 decoding, we decode multiples of 4 bytes until /* for a possible base64 decoding, we decode multiples of 4 bytes until
* the whole frame is received and carry over any remaining bytes in the carry buf*/ * the whole frame is received and carry over any remaining bytes in the carry buf*/
data = (unsigned char *)hybiPayloadStart(wsctx); data = (unsigned char *)(wsctx->writePos - toDecode);
data32= (uint32_t *)data; data32= (uint32_t *)data;
for (i = 0; i < (toDecode >> 2); i++) { for (i = 0; i < (toDecode >> 2); i++) {
@ -321,24 +327,25 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
} }
rfbLog("carrying over %d bytes from %p to %p\n", wsctx->carrylen, wsctx->writePos + (i * 4), wsctx->carryBuf); rfbLog("carrying over %d bytes from %p to %p\n", wsctx->carrylen, wsctx->writePos + (i * 4), wsctx->carryBuf);
memcpy(wsctx->carryBuf, data + (i * 4), wsctx->carrylen); memcpy(wsctx->carryBuf, data + (i * 4), wsctx->carrylen);
wsctx->writePos -= wsctx->carrylen;
} }
toReturn = toDecode - wsctx->carrylen; toReturn = toDecode - wsctx->carrylen;
switch (wsctx->header.opcode) { switch (wsctx->header.opcode) {
case WS_OPCODE_CLOSE: case WS_OPCODE_CLOSE:
/* this data is not returned as payload data */ /* this data is not returned as payload data */
if (hybiWsFrameComplete(wsctx)) { if (hybiWsFrameComplete(wsctx)) {
rfbLog("got close cmd, reason %d\n", WS_NTOH16(((uint16_t *)data)[0])); *(wsctx->writePos) = '\0';
rfbLog("got close cmd %d, reason %d: %s\n", (int)(wsctx->writePos - hybiPayloadStart(wsctx)), WS_NTOH16(((uint16_t *)hybiPayloadStart(wsctx))[0]), &hybiPayloadStart(wsctx)[2]);
errno = ECONNRESET; errno = ECONNRESET;
*sockRet = -1; *sockRet = -1;
return WS_HYBI_STATE_FRAME_COMPLETE; return WS_HYBI_STATE_FRAME_COMPLETE;
} else { } else {
rfbErr("%s: close reason with long frame not supported", __func__); rfbLog("got close cmd; waiting for %d more bytes to arrive\n", hybiRemaining(wsctx));
errno = EIO;
*sockRet = -1; *sockRet = -1;
return WS_HYBI_STATE_ERR; errno = EAGAIN;
return WS_HYBI_STATE_CLOSE_REASON_PENDING;
} }
break; break;
case WS_OPCODE_TEXT_FRAME: case WS_OPCODE_TEXT_FRAME:
@ -412,25 +419,26 @@ webSocketsDecodeHybi(ws_ctx_t *wsctx, char *dst, int len)
wsctx->nReadRaw, wsctx->carrylen, wsctx->carryBuf); wsctx->nReadRaw, wsctx->carrylen, wsctx->carryBuf);
switch (wsctx->hybiDecodeState){ switch (wsctx->hybiDecodeState){
int nInBuf;
case WS_HYBI_STATE_HEADER_PENDING: case WS_HYBI_STATE_HEADER_PENDING:
wsctx->hybiDecodeState = hybiReadHeader(wsctx, &result); wsctx->hybiDecodeState = hybiReadHeader(wsctx, &result, &nInBuf);
if (wsctx->hybiDecodeState == WS_HYBI_STATE_ERR) { if (wsctx->hybiDecodeState == WS_HYBI_STATE_ERR) {
goto spor; goto spor;
} }
if (wsctx->hybiDecodeState != WS_HYBI_STATE_HEADER_PENDING) { if (wsctx->hybiDecodeState != WS_HYBI_STATE_HEADER_PENDING) {
/* when header is complete, try to read some more data */ /* when header is complete, try to read some more data */
wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result); wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, nInBuf);
} }
break; break;
case WS_HYBI_STATE_DATA_AVAILABLE: case WS_HYBI_STATE_DATA_AVAILABLE:
wsctx->hybiDecodeState = hybiReturnData(dst, len, wsctx, &result); wsctx->hybiDecodeState = hybiReturnData(dst, len, wsctx, &result);
break; break;
case WS_HYBI_STATE_DATA_NEEDED: case WS_HYBI_STATE_DATA_NEEDED:
wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result); wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, 0);
break; break;
case WS_HYBI_STATE_CLOSE_REASON_PENDING: case WS_HYBI_STATE_CLOSE_REASON_PENDING:
wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result); wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, 0);
break; break;
default: default:
/* invalid state */ /* invalid state */

@ -7,13 +7,6 @@
#include <resolv.h> /* __b64_ntop */ #include <resolv.h> /* __b64_ntop */
#endif #endif
enum {
WEBSOCKETS_VERSION_HIXIE,
WEBSOCKETS_VERSION_HYBI
};
#if defined(__APPLE__) #if defined(__APPLE__)
#include <libkern/OSByteOrder.h> #include <libkern/OSByteOrder.h>

@ -26,6 +26,14 @@ import websockets
import base64 import base64
import errno import errno
'''
Create websocket frames for the wstest websocket decoding unit test.
Generates c ws_frame_test structure definitions
included by wstest.c.
'''
def add_field(s, name, value, first=False): def add_field(s, name, value, first=False):
deli = ",\n\t\t" deli = ",\n\t\t"
if first: if first:
@ -35,10 +43,9 @@ def add_field(s, name, value, first=False):
class Testframe(): class Testframe():
def __init__(self, frame, descr, retbytes=[], modify_bytes={}, experrno=0, mask=True): def __init__(self, frame, descr, modify_bytes={}, experrno=0, mask=True):
self.frame = frame self.frame = frame
self.descr = descr self.descr = descr
self.retbytes = retbytes
self.modify_bytes = modify_bytes self.modify_bytes = modify_bytes
self.experrno = experrno self.experrno = experrno
self.b64 = True if frame.opcode == 1 else False self.b64 = True if frame.opcode == 1 else False
@ -53,7 +60,7 @@ class Testframe():
for k in self.modify_bytes: for k in self.modify_bytes:
values[k] = "0X{0:02X}".format(self.modify_bytes[k]) values[k] = "0X{0:02X}".format(self.modify_bytes[k])
return "{{{0}}}".format(", ".join(values)) return "{{{0}}}".format(",".join(values))
def set_frame_buf(self, buf): def set_frame_buf(self, buf):
@ -61,14 +68,13 @@ class Testframe():
self.framelen = len(buf) self.framelen = len(buf)
def __str__(self): def __str__(self):
#print("processing frame: {0}".format(self.descr)) print("processing frame: {0}".format(self.descr))
the_frame = self.frame the_frame = self.frame
if self.b64: if self.b64:
olddata = self.frame.data olddata = self.frame.data
newdata = base64.b64encode(self.frame.data) newdata = base64.b64encode(self.frame.data)
#print("converting\n{0}\nto{1}\n".format(olddata, newdata)) #print("converting\n{0}\nto{1}\n".format(olddata, newdata))
the_frame = websockets.framing.Frame(self.frame.fin, self.frame.opcode, base64.b64encode(olddata)) the_frame = websockets.framing.Frame(self.frame.fin, self.frame.opcode, base64.b64encode(olddata))
websockets.framing.write_frame(the_frame, self.set_frame_buf, self.mask) websockets.framing.write_frame(the_frame, self.set_frame_buf, self.mask)
s = "\t{\n" s = "\t{\n"
s = add_field(s, "frame", "{0}".format(self.frame_carray), True) s = add_field(s, "frame", "{0}".format(self.frame_carray), True)
@ -77,8 +83,6 @@ class Testframe():
s = add_field(s, "raw_payload_len", len(self.frame.data)) s = add_field(s, "raw_payload_len", len(self.frame.data))
s = add_field(s, "expected_errno", self.experrno) s = add_field(s, "expected_errno", self.experrno)
s = add_field(s, "descr", "\"{0}\"".format(self.descr)) s = add_field(s, "descr", "\"{0}\"".format(self.descr))
s = add_field(s, "ret_bytes", "{{{0}}}".format(", ".join(self.retbytes)))
s = add_field(s, "ret_bytes_len", len(self.retbytes))
s = add_field(s, "i", "0") s = add_field(s, "i", "0")
s = add_field(s, "simulate_sock_malfunction_at", "0") s = add_field(s, "simulate_sock_malfunction_at", "0")
s = add_field(s, "errno_val", "0") s = add_field(s, "errno_val", "0")
@ -89,25 +93,25 @@ class Testframe():
### create test frames ### create test frames
flist = [] flist = []
### standard text frames with different lengths ### standard text frames with different lengths
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Short valid text frame", {})) flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Short valid text frame"))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")), flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")),
"Mid-long valid text frame", {})) "Mid-long valid text frame"))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray([(x % 26) + 65 for x in range(100000)])), "100k text frame (ABC..YZABC..)", {})) #flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray([(x % 26) + 65 for x in range(100000)])), "100k text frame (ABC..YZABC..)"))
### standard binary frames with different lengths ### standard binary frames with different lengths
flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Testit", encoding="utf-8")), "Short valid binary frame", {})) flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Testit", encoding="utf-8")), "Short valid binary frame"))
flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")), flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")),
"Mid-long valid binary frame", {})) "Mid-long valid binary frame"))
flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray([(x % 26) + 65 for x in range(100000)])), "100k binary frame (ABC..YZABC..)", {})) #flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray([(x % 26) + 65 for x in range(100000)])), "100k binary frame (ABC..YZABC..)"))
### some conn reset frames, one with no close message, one with close message (the latter should cause an error) ### some conn reset frames, one with no close message, one with close message
flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB]))), "Close frame (Reason 1003)", {}, experrno=errno.ECONNRESET)) flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB]))), "Close frame (Reason 1003)", experrno=errno.ECONNRESET))
flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB])) + bytearray("I'm a close reason", encoding="utf-8")), "Close frame (Reason 1003) and msg", {}, experrno=errno.EIO)) flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB])) + bytearray("I'm a close reason and much more than that!", encoding="utf-8")), "Close frame (Reason 1003) and msg", experrno=errno.ECONNRESET))
### invalid header values ### invalid header values
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", {}, experrno=errno.EPROTO, mask=False)) flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", experrno=errno.EPROTO, mask=False))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("..Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 16 bit len field", {}, experrno=errno.EPROTO, modify_bytes={ 1: 0xFE, 2: 0x00, 3: 0x0F})) flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("..Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 16 bit len field", experrno=errno.EPROTO, modify_bytes={ 1: 0xFE, 2: 0x00, 3: 0x0F}))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("........Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 64 bit len field", {}, experrno=errno.EPROTO, modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x80, 7: 0x40})) flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("........Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 64 bit len field", experrno=errno.EPROTO, modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x80, 7: 0x40}))
s = "struct ws_frame_test tests[] = {\n" s = "struct ws_frame_test tests[] = {\n"
for i in range(len(flist)): for i in range(len(flist)):
@ -117,5 +121,5 @@ for i in range(len(flist)):
s += "\n" s += "\n"
s += "};\n" s += "};\n"
with open("wstestdata.in", "w") as cdatafile: with open("wstestdata.c", "w") as cdatafile:
cdatafile.write(s) cdatafile.write(s)

@ -23,6 +23,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _WIN32
#include <ws_decode.h> #include <ws_decode.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -30,11 +32,11 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32 /* incoming data frames should not be larger than that */
#define TEST_BUF_SIZE B64LEN(131072) + WSHLENMAX #define TEST_BUF_SIZE B64LEN(131072) + WSHLENMAX
/* seed is fixed deliberately to get reproducible test cases */
#define RND_SEED 100 #define RND_SEED 100
#define WS_TMP_LOG "ws_tmp.log"
enum { enum {
OK, OK,
@ -55,6 +57,7 @@ struct ws_frame_test {
char frame[TEST_BUF_SIZE]; char frame[TEST_BUF_SIZE];
char *pos; char *pos;
char expectedDecodeBuf[TEST_BUF_SIZE]; char expectedDecodeBuf[TEST_BUF_SIZE];
uint64_t n_compare;
uint64_t frame_len; uint64_t frame_len;
uint64_t raw_payload_len; uint64_t raw_payload_len;
int expected_errno; int expected_errno;
@ -67,6 +70,8 @@ struct ws_frame_test {
int close_sock_at; int close_sock_at;
}; };
#include "wstestdata.c"
char el_log[1000000]; char el_log[1000000];
char *el_pos; char *el_pos;
@ -160,15 +165,15 @@ static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx)
return OK; return OK;
} }
#include "wstestdata.in"
int main() int main()
{ {
ws_ctx_t ctx; ws_ctx_t ctx;
int retall= 0; int retall= 0;
int i;
srand(RND_SEED); srand(RND_SEED);
for (int i = 0; i < ARRAYSIZE(tests); i++) { for (i = 0; i < ARRAYSIZE(tests); i++) {
int ret; int ret;
el_pos = el_log; el_pos = el_log;
@ -192,4 +197,10 @@ int main()
return retall; return retall;
} }
#else
int main() {
return 0;
}
#endif #endif

@ -0,0 +1,110 @@
struct ws_frame_test tests[] = {
{
.frame={0X81,0X88,0XB7,0XDB,0X16,0X16,0XE1,0X9C,0X40,0X6C,0XD3,0X9C,0X7A,0X26},
.expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
.frame_len=14,
.raw_payload_len=6,
.expected_errno=0,
.descr="Short valid text frame",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X81,0XFE,0X00,0XD4,0X67,0XFE,0X8A,0X31,0X35,0X90,0XC0,0X59,0X05,0XA9,0XDF,0X48,0X2E,0XB9,0XD8,0X47,0X3D,0XA6,0XC7,0X56,0X3E,0XCC,0XB3,0X44,0X03,0XB9,0XCC,0X41,0X05,0X97,0XC8,0X45,0X03,0XA9,0XC4,0X5E,0X2E,0XB9,0XBB,0X47,0X04,0X93,0XDF,0X56,0X03,0XB9,0XDC,0X05,0X03,0XBD,0XC8,0X59,0X05,0X93,0XDB,0X56,0X3D,0XA6,0XD0,0X5D,0X05,0X97,0XC8,0X5F,0X05,0XCC,0XDC,0X4B,0X2E,0XB9,0XC0,0X5D,0X02,0XA9,0XB3,0X44,0X3D,0XBD,0XC8,0X01,0X06,0XB9,0XDF,0X56,0X2A,0XAA,0XC3,0X03,0X2E,0XB9,0XC0,0X04,0X03,0XB9,0XDF,0X56,0X05,0XB9,0XDC,0X44,0X2E,0XB9,0XD0,0X41,0X3D,0XA9,0XF2,0X5A,0X2B,0X97,0XC8,0X76,0X04,0X93,0XCC,0X45,0X3D,0XAA,0XC3,0X56,0X3D,0XB9,0XB3,0X5D,0X04,0X87,0XC8,0X5B,0X05,0XCC,0XBF,0X01,0X3E,0XA9,0XE6,0X44,0X2E,0XB9,0XBB,0X00,0X3E,0XCC,0XED,0X56,0X05,0XA9,0XB3,0X48,0X3D,0XAD,0XC8,0X01,0X3D,0XA6,0XE2,0X01,0X2E,0XB9,0XCC,0X44,0X3D,0XBD,0XC8,0X5D,0X03,0X93,0XDC,0X44,0X2E,0XB9,0XEE,0X47,0X3D,0XA6,0XC7,0X56,0X3E,0X93,0XDC,0X04,0X05,0XCC,0XBF,0X5A,0X2E,0XB6,0XD8,0X5E,0X3D,0XAD,0XCB,0X49,0X2A,0X94,0XD3,0X56,0X3E,0X90,0XE6,0X01,0X3D,0XAD,0XC8,0X42,0X3D,0XA9,0XBE,0X56,0X3D,0X93,0XE6,0X5D,0X05,0XB9,0XDB,0X44},
.expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E},
.frame_len=220,
.raw_payload_len=159,
.expected_errno=0,
.descr="Mid-long valid text frame",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X82,0X86,0X90,0X5E,0X2B,0X8E,0XC4,0X3B,0X58,0XFA,0XF9,0X2A},
.expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
.frame_len=12,
.raw_payload_len=6,
.expected_errno=0,
.descr="Short valid binary frame",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X82,0XFE,0X00,0X9F,0X7D,0X97,0X6B,0XA2,0X3B,0XE5,0X0A,0XCF,0X18,0XA5,0X4B,0XC6,0X12,0XF2,0X18,0X82,0X1E,0XF8,0X05,0XD6,0X1C,0XFE,0X05,0X82,0X10,0XE2,0X08,0XCA,0X5D,0XFA,0X04,0XD0,0X18,0XB7,0X1F,0XC7,0X05,0XE3,0X4B,0XC3,0X13,0XF3,0X4B,0XC7,0X0B,0XF2,0X05,0X82,0X1A,0XF8,0X0E,0XD1,0X5D,0XF5,0X0E,0XDB,0X12,0XF9,0X0F,0X82,0X09,0XFF,0X0E,0X82,0X4C,0XA5,0X5D,0X82,0X1F,0XEE,0X1F,0XC7,0X5D,0XFB,0X0E,0XCC,0X5D,0XF1,0X02,0XC7,0X11,0XF3,0X45,0X82,0X3B,0XE5,0X0A,0XCF,0X18,0XA5,0X4B,0XC6,0X12,0XF2,0X18,0X82,0X1E,0XF8,0X05,0XD6,0X1C,0XFE,0X05,0X82,0X10,0XE2,0X08,0XCA,0X5D,0XFA,0X04,0XD0,0X18,0XB7,0X1F,0XC7,0X05,0XE3,0X4B,0XC3,0X13,0XF3,0X4B,0XC7,0X0B,0XF2,0X05,0X82,0X1A,0XF8,0X0E,0XD1,0X5D,0XF5,0X0E,0XDB,0X12,0XF9,0X0F,0X82,0X09,0XFF,0X0E,0X82,0X4C,0XA5,0X5D,0X82,0X1F,0XEE,0X1F,0XC7,0X5D,0XFB,0X0E,0XCC,0X5D,0XF1,0X02,0XC7,0X11,0XF3,0X45},
.expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E},
.frame_len=167,
.raw_payload_len=159,
.expected_errno=0,
.descr="Mid-long valid binary frame",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X88,0X82,0X71,0X1D,0X00,0XFE,0X72,0XF6},
.expectedDecodeBuf={0X03,0XEB},
.frame_len=8,
.raw_payload_len=2,
.expected_errno=104,
.descr="Close frame (Reason 1003)",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X88,0XAD,0XD0,0X8D,0X26,0XD8,0XD3,0X66,0X6F,0XFF,0XBD,0XAD,0X47,0XF8,0XB3,0XE1,0X49,0XAB,0XB5,0XAD,0X54,0XBD,0XB1,0XFE,0X49,0XB6,0XF0,0XEC,0X48,0XBC,0XF0,0XE0,0X53,0XBB,0XB8,0XAD,0X4B,0XB7,0XA2,0XE8,0X06,0XAC,0XB8,0XEC,0X48,0XF8,0XA4,0XE5,0X47,0XAC,0XF1},
.expectedDecodeBuf={0X03,0XEB,0X49,0X27,0X6D,0X20,0X61,0X20,0X63,0X6C,0X6F,0X73,0X65,0X20,0X72,0X65,0X61,0X73,0X6F,0X6E,0X20,0X61,0X6E,0X64,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X68,0X61,0X6E,0X20,0X74,0X68,0X61,0X74,0X21},
.frame_len=51,
.raw_payload_len=45,
.expected_errno=104,
.descr="Close frame (Reason 1003) and msg",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X81,0X08,0X56,0X47,0X56,0X7A,0X64,0X47,0X6C,0X30},
.expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
.frame_len=10,
.raw_payload_len=6,
.expected_errno=71,
.descr="Invalid frame: Wrong masking",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X81,0XFE,0X00,0X0F,0X24,0X22,0X8D,0X9C,0X11,0X6F,0XA3,0XC6,0X6E,0X4E,0X88,0XB0,0X48,0X55,0XA2,0XC6,0X72,0X56},
.expectedDecodeBuf={0X2E,0XFE,0X00,0X0F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
.frame_len=22,
.raw_payload_len=12,
.expected_errno=71,
.descr="Invalid frame: Length of < 126 with add. 16 bit len field",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X81,0XFF,0X00,0X00,0X00,0X00,0X80,0X40,0X7D,0XBB,0X03,0X56,0X7D,0XBB,0X03,0X56,0X7C,0X83,0X2D,0X0C,0X03,0XA2,0X06,0X7A,0X25,0XB9,0X2C,0X0C,0X1F,0XBA},
.expectedDecodeBuf={0X2E,0XFF,0X00,0X00,0X00,0X00,0X80,0X40,0X4C,0X6F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
.frame_len=30,
.raw_payload_len=18,
.expected_errno=71,
.descr="Invalid frame: Length of < 126 with add. 64 bit len field",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
}
};
Loading…
Cancel
Save