aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2020-10-14 19:41:42 +0200
committerKim Alvefur <zash@zash.se>2020-10-14 19:41:42 +0200
commit2fa0aa06d5d8b4f28e038e9bf8179f61ce3c6ba5 (patch)
tree676d8df02e0a42ffb5b6f646192e57e3a625fd49
parent5d87a7d46ffa09262fcc6813b7bc6ce63992abd1 (diff)
downloadprosody-2fa0aa06d5d8b4f28e038e9bf8179f61ce3c6ba5.tar.gz
prosody-2fa0aa06d5d8b4f28e038e9bf8179f61ce3c6ba5.zip
net.websocket.frames: Use C string XOR implementation
-rw-r--r--net/websocket/frames.lua30
-rw-r--r--spec/net_websocket_frames_spec.lua2
2 files changed, 8 insertions, 24 deletions
diff --git a/net/websocket/frames.lua b/net/websocket/frames.lua
index 9cb5f4fe..1d0ac06f 100644
--- a/net/websocket/frames.lua
+++ b/net/websocket/frames.lua
@@ -13,12 +13,11 @@ local bit = assert(softreq"bit" or softreq"bit32",
"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 @@ local function parse_frame_header(frame)
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 @@ end
-- 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 function build_frame(desc)
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 --git a/spec/net_websocket_frames_spec.lua b/spec/net_websocket_frames_spec.lua
index 9499cee7..244afa3b 100644
--- a/spec/net_websocket_frames_spec.lua
+++ b/spec/net_websocket_frames_spec.lua
@@ -36,7 +36,7 @@ describe("net.websocket.frames", function ()
["opcode"] = 0;
["length"] = 5;
["data"] = "hello";
- ["key"] = { 32, 0, 32, 0, };
+ ["key"] = " \0 \0";
["FIN"] = true;
["MASK"] = true;
["RSV1"] = false;