# HG changeset patch # User Kim Alvefur # Date 1602697302 -7200 # Node ID 4e5a2af9dd19d7d20380d1b16646c16a5c50e59b # Parent 37a6a535343e502315921218ca4ac0f3054fc420 net.websocket.frames: Use C string XOR implementation diff -r 37a6a535343e -r 4e5a2af9dd19 net/websocket/frames.lua --- a/net/websocket/frames.lua Sat Sep 07 13:37:47 2019 +0200 +++ b/net/websocket/frames.lua Wed Oct 14 19:41:42 2020 +0200 @@ -13,12 +13,11 @@ "No bit module found. See https://prosody.im/doc/depends#bitop"); local band = bit.band; local bor = bit.bor; -local bxor = bit.bxor; local lshift = bit.lshift; local rshift = bit.rshift; -local unpack = table.unpack or unpack; -- luacheck: ignore 113 +local sbit = require "util.strbitop"; +local sxor = sbit.sxor; -local t_concat = table.concat; local s_char= string.char; local s_pack = string.pack; -- luacheck: ignore 143 local s_unpack = string.unpack; -- luacheck: ignore 143 @@ -107,7 +106,7 @@ end if result.MASK then - result.key = { frame:byte(length_bytes+3, length_bytes+6) }; + result.key = frame:sub(length_bytes+3, length_bytes+6); end return result, header_length; @@ -116,19 +115,7 @@ -- XORs the string `str` with the array of bytes `key` -- TODO: optimize local function apply_mask(str, key, from, to) - from = from or 1 - if from < 0 then from = #str + from + 1 end -- negative indices - to = to or #str - if to < 0 then to = #str + to + 1 end -- negative indices - local key_len = #key - local counter = 0; - local data = {}; - for i = from, to do - local key_index = counter%key_len + 1; - counter = counter + 1; - data[counter] = s_char(bxor(key[key_index], str:byte(i))); - end - return t_concat(data); + return sxor(str:sub(from or 1, to or -1), key); end local function parse_frame_body(frame, header, pos) @@ -175,15 +162,12 @@ local key = "" if desc.MASK then - local key_a = desc.key - if key_a then - key = s_char(unpack(key_a, 1, 4)); - else + key = desc.key + if not key then key = random_bytes(4); - key_a = {key:byte(1,4)}; end b2 = bor(b2, 0x80); - data = apply_mask(data, key_a); + data = apply_mask(data, key); end return s_char(b1, b2) .. length_extra .. key .. data diff -r 37a6a535343e -r 4e5a2af9dd19 spec/net_websocket_frames_spec.lua --- a/spec/net_websocket_frames_spec.lua Sat Sep 07 13:37:47 2019 +0200 +++ b/spec/net_websocket_frames_spec.lua Wed Oct 14 19:41:42 2020 +0200 @@ -36,7 +36,7 @@ ["opcode"] = 0; ["length"] = 5; ["data"] = "hello"; - ["key"] = { 32, 0, 32, 0, }; + ["key"] = " \0 \0"; ["FIN"] = true; ["MASK"] = true; ["RSV1"] = false;