From 44a7f65e1a36b972670a7a063c8ceb3893f761d1 Mon Sep 17 00:00:00 2001
From: Andy Green <andy.green@linaro.org>
Date: Tue, 29 Dec 2015 11:20:09 +0800
Subject: [PATCH] introduce LWS_SERVER_OPTION_VALIDATE_UTF8

Signed-off-by: Andy Green <andy.green@linaro.org>
---
 changelog               | 16 ++++++++++++++++
 lib/client-parser.c     | 11 ++++++-----
 lib/libwebsockets.h     |  3 ++-
 test-server/test-echo.c |  2 +-
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/changelog b/changelog
index 59604d01..bd483950 100644
--- a/changelog
+++ b/changelog
@@ -99,6 +99,14 @@ The browser shows the close code and reason he received
 
 websocket connection CLOSED, code: 1001, reason: seeya
 
+3) There's a new context creation time option flag
+
+LWS_SERVER_OPTION_VALIDATE_UTF8
+
+if you set it in info->options, then TEXT and CLOSE frames will get checked to
+confirm that they contain valid UTF-8.  If they don't, the connection will get
+closed by lws.
+
 
 User api changes
 ----------------
@@ -117,6 +125,14 @@ LWS_WRITE_CLOSE is removed from libwebsockets.h.  It was only of use to send
 close frames...close frame content should be managed using lws_close_reason()
 now.
 
+3) We check for invalid CLOSE codes and complain about protocol violation in
+our close code.  But it changes little since we were in the middle of closing
+anyway.
+
+4) zero-length RX frames and zero length TX frames are now allowed.
+
+5) Pings and close used to be limited to 124 bytes, the correct limit is 125
+so that is now also allowed.
 
 
 v1.6.0-chrome48-firefox42
diff --git a/lib/client-parser.c b/lib/client-parser.c
index 6d511ea1..72e19f6a 100644
--- a/lib/client-parser.c
+++ b/lib/client-parser.c
@@ -282,11 +282,12 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
 			c ^= wsi->u.ws.mask_nonce[
 					    (wsi->u.ws.frame_mask_index++) & 3];
 
-		if ((!wsi->u.ws.frame_is_binary &&
-		     wsi->u.ws.opcode == LWSWSOPC_CONTINUATION) ||
-		     wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME ||
-		    (wsi->u.ws.opcode == LWSWSOPC_CLOSE &&
-		     wsi->u.ws.rx_user_buffer_head > 2)) {
+		if ((wsi->context->options & LWS_SERVER_OPTION_VALIDATE_UTF8) &&
+		    ((!wsi->u.ws.frame_is_binary &&
+		      (wsi->u.ws.opcode == LWSWSOPC_CONTINUATION ||
+		       wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME)) ||
+		     (wsi->u.ws.opcode == LWSWSOPC_CLOSE &&
+		      wsi->u.ws.rx_user_buffer_head > 2))) {
 			static const unsigned char e0f4[] = {
 				0xa0 | ((2 - 1) << 2) | 1, /* e0 */
 				0x80 | ((4 - 1) << 2) | 1, /* e1 */
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 830fc407..129f776d 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -270,6 +270,7 @@ enum lws_context_options {
 	LWS_SERVER_OPTION_DISABLE_IPV6				= (1 << 5),
 	LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS			= (1 << 6),
 	LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED		= (1 << 7),
+	LWS_SERVER_OPTION_VALIDATE_UTF8				= (1 << 8),
 
 	/****** add new things just above ---^ ******/
 };
@@ -1242,7 +1243,7 @@ struct lws_extension {
  * @http_proxy_port:	If http_proxy_address was non-NULL, uses this port at the address
  * @gid:	group id to change to after setting listen socket, or -1.
  * @uid:	user id to change to after setting listen socket, or -1.
- * @options:	0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
+ * @options:	0, or LWS_SERVER_OPTION_... bitfields
  * @user:	optional user pointer that can be recovered via the context
  *		pointer using lws_context_user
  * @ka_time:	0 for no keepalive, otherwise apply this keepalive timeout to
diff --git a/test-server/test-echo.c b/test-server/test-echo.c
index 0d642f04..14be18e2 100644
--- a/test-server/test-echo.c
+++ b/test-server/test-echo.c
@@ -409,7 +409,7 @@ int main(int argc, char **argv)
 		}
 	info.gid = -1;
 	info.uid = -1;
-	info.options = opts;
+	info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8;
 
 	context = lws_create_context(&info);
 	if (context == NULL) {
-- 
GitLab