]> granicus.if.org Git - apache/commitdiff
Fix bit-shifting of websockets frame fields that would yield wrong opcodes
authorEric Covener <covener@apache.org>
Wed, 4 Feb 2015 14:33:51 +0000 (14:33 +0000)
committerEric Covener <covener@apache.org>
Wed, 4 Feb 2015 14:33:51 +0000 (14:33 +0000)
when the FIN bit was set.  Results in PING not being recognized
by mod_lua.  PR57524

Submitted By: Edward Lu
Committed By: covener

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1657256 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/lua/lua_request.c

diff --git a/CHANGES b/CHANGES
index 1fdb46dd242326f954c769577fd167c38234e370..aa79dac9c682ca9cbaa4368ac5f049e64e671cb8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_lua: After a r:wsupgrade(), mod_lua was not properly
+     responding to a websockets PING but instead invoking the specified 
+     script. PR57524. [Edward Lu <Chaosed0 gmail.com>]
+
   *) mod_macro: Clear macros before initialization to avoid use-after-free
      on startup or restart when the module is linked statically. PR 57525
      [apache.org tech.futurequest.net, Yann Ylavic]
index e44009c0348773c89cc2b81a11b9611546bb4821..dded599a4c7d8803b5ee5aa70008195a5fa87509 100644 (file)
@@ -2252,9 +2252,12 @@ static int lua_websocket_read(lua_State *L)
         rv = lua_websocket_readbytes(r->connection, &byte, 1);
     }
     if (rv == APR_SUCCESS) {
-        unsigned char fin, opcode, mask, payload;
-        fin = byte >> 7;
-        opcode = (byte << 4) >> 4;
+        unsigned char ubyte, fin, opcode, mask, payload;
+        ubyte = (unsigned char)byte;
+        /* fin bit is the first bit */
+        fin = ubyte >> (CHAR_BIT - 1);
+        /* opcode is the last four bits (there's 3 reserved bits we don't care about) */
+        opcode = ubyte & 0xf;
         
         /* Get the payload length and mask bit */
         if (plaintext) {
@@ -2264,14 +2267,18 @@ static int lua_websocket_read(lua_State *L)
             rv = lua_websocket_readbytes(r->connection, &byte, 1);
         }
         if (rv == APR_SUCCESS) {
-            mask = byte >> 7;
-            payload = byte - 128;
+            ubyte = (unsigned char)byte;
+            /* Mask is the first bit */
+            mask = ubyte >> (CHAR_BIT - 1);
+            /* Payload is the last 7 bits */
+            payload = ubyte & 0x7f;
             plen = payload;
             
             /* Extended payload? */
             if (payload == 126) {
                 len = 2;
                 if (plaintext) {
+                    /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
                     rv = apr_socket_recv(sock, (char*) &payload_short, &len);
                 }
                 else {