Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package prosody for openSUSE:Factory checked in at 2021-02-16 22:40:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/prosody (Old) and /work/SRC/openSUSE:Factory/.prosody.new.28504 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "prosody" Tue Feb 16 22:40:41 2021 rev:22 rq:872807 version:0.11.8 Changes: -------- --- /work/SRC/openSUSE:Factory/prosody/prosody.changes 2020-10-02 17:40:28.970852382 +0200 +++ /work/SRC/openSUSE:Factory/.prosody.new.28504/prosody.changes 2021-02-16 22:51:05.610713667 +0100 @@ -1,0 +2,30 @@ +Tue Feb 16 11:06:40 UTC 2021 - Michael Vetter <[email protected]> + +- Update to 0.11.8: + Security: + * mod_saslauth: Disable ???tls-unique??? channel binding with TLS 1.3 (#1542) + Fixes and improvements: + * net.websocket.frames: Improve websocket masking performance by using the new util.strbitop + * util.strbitop: Library for efficient bitwise operations on strings + Minor changes: + * MUC: Correctly advertise whether the subject can be changed (#1155) + * MUC: Preserve disco ???node??? attribute (or lack thereof) in responses (#1595) + * MUC: Fix logic bug causing unnecessary presence to be sent (#1615) + * mod_bosh: Fix error if client tries to connect to component (#425) + * mod_bosh: Pick out the ???wait??? before checking it instead of earlier + * mod_pep: Advertise base PubSub feature (#1632) + * mod_pubsub: Fix notification stanza type setting (#1605) + * mod_s2s: Prevent keepalives before client has established a stream + * net.adns: Fix bug that sent empty DNS packets (#1619) + * net.http.server: Don???t send Content-Length on 1xx/204 responses (#1596) + * net.websocket.frames: Fix length calculation bug (#1598) + * util.dbuffer: Make length API in line with Lua strings + * util.dbuffer: Optimize substring operations + * util.debug: Fix locals being reported under wrong stack frame in some cases + * util.dependencies: Fix check for Lua bitwise operations library (#1594) + * util.interpolation: Fix combination of filters and fallback values #1623 + * util.promise: Preserve tracebacks + * util.stanza: Reject ASCII control characters (#1606) + * timers: Ensure timers can???t block other processing (#1620) + +------------------------------------------------------------------- Old: ---- prosody-0.11.7.tar.gz prosody-0.11.7.tar.gz.asc New: ---- prosody-0.11.8.tar.gz prosody-0.11.8.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ prosody.spec ++++++ --- /var/tmp/diff_new_pack.QQ9uZF/_old 2021-02-16 22:51:06.326714599 +0100 +++ /var/tmp/diff_new_pack.QQ9uZF/_new 2021-02-16 22:51:06.330714604 +0100 @@ -1,7 +1,7 @@ # # spec file for package prosody # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define _piddir /run Name: prosody -Version: 0.11.7 +Version: 0.11.8 Release: 0 Summary: Communications server for Jabber/XMPP License: MIT ++++++ prosody-0.11.7.tar.gz -> prosody-0.11.8.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/.hg_archival.txt new/prosody-0.11.8/.hg_archival.txt --- old/prosody-0.11.7/.hg_archival.txt 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/.hg_archival.txt 2021-02-15 16:29:13.000000000 +0100 @@ -1,4 +1,4 @@ repo: 3e3171b59028ee70122cfec6ecf98f518f946b59 -node: ece430d4980997b216c2240015bf922bdeb12dd6 +node: 774811e2c6abfc5a1b1dd60007cf564bb7c1f969 branch: 0.11 -tag: 0.11.7 +tag: 0.11.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/net/adns.lua new/prosody-0.11.8/net/adns.lua --- old/prosody-0.11.7/net/adns.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/net/adns.lua 2021-02-15 16:29:13.000000000 +0100 @@ -50,6 +50,11 @@ if not handler then return nil, err; end + if handler.set then + -- server_epoll: only watch for incoming data + -- avoids sending empty packet on first 'onwritable' event + handler:set(true, false); + end handler.settimeout = function () end handler.setsockname = function (_, ...) return sock:setsockname(...); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/net/http/server.lua new/prosody-0.11.8/net/http/server.lua --- old/prosody-0.11.7/net/http/server.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/net/http/server.lua 2021-02-15 16:29:13.000000000 +0100 @@ -295,7 +295,10 @@ function _M.send_response(response, body) if response.finished then return; end body = body or response.body or ""; - response.headers.content_length = #body; + -- Per RFC 7230, informational (1xx) and 204 (no content) should have no c-l header + if response.status_code > 199 and response.status_code ~= 204 then + response.headers.content_length = #body; + end local output = prepare_header(response); t_insert(output, body); response.conn:write(t_concat(output)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/net/server_epoll.lua new/prosody-0.11.8/net/server_epoll.lua --- old/prosody-0.11.7/net/server_epoll.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/net/server_epoll.lua 2021-02-15 16:29:13.000000000 +0100 @@ -97,10 +97,10 @@ -- Any timers at all? local now = gettime(); local peek = timers:peek(); + local readd; while peek do if peek > now then - next_delay = peek - now; break; end @@ -109,13 +109,29 @@ if ok and type(ret) == "number" then local next_time = now+ret; timer[1] = next_time; - timers:insert(timer, next_time); + -- Delay insertion of timers to be re-added + -- so they don't get called again this tick + if readd then + readd[id] = timer; + else + readd = { [id] = timer }; + end end peek = timers:peek(); end + + if readd then + for _, timer in pairs(readd) do + timers:insert(timer, timer[1]); + end + peek = timers:peek(); + end + if peek == nil then return next_delay; + else + next_delay = peek - now; end if next_delay < min_wait then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/net/websocket/frames.lua new/prosody-0.11.8/net/websocket/frames.lua --- old/prosody-0.11.7/net/websocket/frames.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/net/websocket/frames.lua 2021-02-15 16:29:13.000000000 +0100 @@ -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 @@ -76,7 +75,7 @@ end local function parse_frame_header(frame) - if #frame < 2 then return; end + if frame:len() < 2 then return; end local byte1, byte2 = frame:byte(1, 2); local result = { @@ -98,7 +97,7 @@ end local header_length = 2 + length_bytes + (result.MASK and 4 or 0); - if #frame < header_length then return; end + if frame:len() < header_length then return; end if length_bytes == 2 then result.length = read_uint16be(frame, 3); @@ -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) @@ -141,7 +128,7 @@ local function parse_frame(frame) local result, pos = parse_frame_header(frame); - if result == nil or #frame < (pos + result.length) then return nil, nil, result; end + if result == nil or frame:len() < (pos + result.length) then return nil, nil, result; end result.data = parse_frame_body(frame, result, pos+1); return result, pos + result.length; end @@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/mod_bosh.lua new/prosody-0.11.8/plugins/mod_bosh.lua --- old/prosody-0.11.7/plugins/mod_bosh.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/mod_bosh.lua 2021-02-15 16:29:13.000000000 +0100 @@ -269,7 +269,6 @@ context.notopen = nil; -- Signals that we accept this opening tag local to_host = nameprep(attr.to); - local wait = tonumber(attr.wait); if not to_host then log("debug", "BOSH client tried to connect to invalid host: %s", tostring(attr.to)); local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", @@ -277,6 +276,24 @@ response:send(tostring(close_reply)); return; end + + if not prosody.hosts[to_host] then + log("debug", "BOSH client tried to connect to non-existant host: %s", attr.to); + local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", + ["xmlns:stream"] = xmlns_streams, condition = "improper-addressing" }); + response:send(tostring(close_reply)); + return; + end + + if prosody.hosts[to_host].type ~= "local" then + log("debug", "BOSH client tried to connect to %s host: %s", prosody.hosts[to_host].type, attr.to); + local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", + ["xmlns:stream"] = xmlns_streams, condition = "improper-addressing" }); + response:send(tostring(close_reply)); + return; + end + + local wait = tonumber(attr.wait); if not rid or (not attr.wait or not wait or wait < 0 or wait % 1 ~= 0) then log("debug", "BOSH client sent invalid rid or wait attributes: rid=%s, wait=%s", tostring(attr.rid), tostring(attr.wait)); local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/mod_pep.lua new/prosody-0.11.8/plugins/mod_pep.lua --- old/prosody-0.11.7/plugins/mod_pep.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/mod_pep.lua 2021-02-15 16:29:13.000000000 +0100 @@ -417,6 +417,7 @@ "presence-subscribe", }; + reply:tag('feature', {var=xmlns_pubsub}):up(); for feature in supported_features do reply:tag('feature', {var=xmlns_pubsub.."#"..feature}):up(); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/mod_pubsub/mod_pubsub.lua new/prosody-0.11.8/plugins/mod_pubsub/mod_pubsub.lua --- old/prosody-0.11.7/plugins/mod_pubsub/mod_pubsub.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/mod_pubsub/mod_pubsub.lua 2021-02-15 16:29:13.000000000 +0100 @@ -72,7 +72,7 @@ end local id = new_id(); - local msg_type = node_obj and node_obj.config.message_type or "headline"; + local msg_type = node_obj and node_obj.config.notification_type or "headline"; local message = st.message({ from = module.host, type = msg_type, id = id }) :tag("event", { xmlns = xmlns_pubsub_event }) :tag(kind, { node = node }) @@ -127,7 +127,7 @@ end end return summary; -end); +end, -1); module:hook("iq/host/"..xmlns_pubsub..":pubsub", handle_pubsub_iq); module:hook("iq/host/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/mod_s2s/mod_s2s.lua new/prosody-0.11.8/plugins/mod_s2s/mod_s2s.lua --- old/prosody-0.11.7/plugins/mod_s2s/mod_s2s.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/mod_s2s/mod_s2s.lua 2021-02-15 16:29:13.000000000 +0100 @@ -163,7 +163,10 @@ end local function keepalive(event) - return event.session.sends2s(' '); + local session = event.session; + if not session.notopen then + return event.session.sends2s(' '); + end end module:hook("s2s-read-timeout", keepalive, -1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/mod_saslauth.lua new/prosody-0.11.8/plugins/mod_saslauth.lua --- old/prosody-0.11.7/plugins/mod_saslauth.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/mod_saslauth.lua 2021-02-15 16:29:13.000000000 +0100 @@ -252,7 +252,10 @@ -- FIXME: would be nice to have this check only once and not for every socket if sasl_handler.add_cb_handler then local socket = origin.conn:socket(); - if socket.getpeerfinished then + local info = socket.info and socket:info(); + if info.protocol == "TLSv1.3" then + log("debug", "Channel binding 'tls-unique' undefined in context of TLS 1.3"); + elseif socket.getpeerfinished and socket:getpeerfinished() then sasl_handler:add_cb_handler("tls-unique", tls_unique); end sasl_handler["userdata"] = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/muc/muc.lib.lua new/prosody-0.11.8/plugins/muc/muc.lib.lua --- old/prosody-0.11.7/plugins/muc/muc.lib.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/muc/muc.lib.lua 2021-02-15 16:29:13.000000000 +0100 @@ -336,12 +336,12 @@ end function room_mt:get_disco_info(stanza) - local node = stanza.tags[1].attr.node or ""; + local node = stanza.tags[1].attr.node; local reply = st.reply(stanza):tag("query", { xmlns = "http://jabber.org/protocol/disco#info", node = node }); local event_name = "muc-disco#info"; local event_data = { room = self, reply = reply, stanza = stanza }; - if node ~= "" then + if node and node ~= "" then event_name = event_name.."/"..node; else event_data.form = dataform.new { @@ -1326,8 +1326,8 @@ if occupant.role == nil then module:fire_event("muc-occupant-left", {room = self; nick = occupant.nick; occupant = occupant;}); elseif is_semi_anonymous and - (old_role == "moderator" and occupant.role ~= "moderator") or - (old_role ~= "moderator" and occupant.role == "moderator") then -- Has gained or lost moderator status + ((old_role == "moderator" and occupant.role ~= "moderator") or + (old_role ~= "moderator" and occupant.role == "moderator")) then -- Has gained or lost moderator status -- Send everyone else's presences (as jid visibility has changed) for real_jid in occupant:each_session() do self:send_occupant_list(real_jid, function(occupant_jid, occupant) --luacheck: ignore 212 433 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/plugins/muc/subject.lib.lua new/prosody-0.11.8/plugins/muc/subject.lib.lua --- old/prosody-0.11.7/plugins/muc/subject.lib.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/plugins/muc/subject.lib.lua 2021-02-15 16:29:13.000000000 +0100 @@ -31,10 +31,10 @@ module:hook("muc-disco#info", function (event) table.insert(event.form, { - name = "muc#roominfo_changesubject"; + name = "muc#roomconfig_changesubject"; type = "boolean"; }); - event.formdata["muc#roominfo_changesubject"] = get_changesubject(event.room); + event.formdata["muc#roomconfig_changesubject"] = get_changesubject(event.room); end); module:hook("muc-config-form", function(event) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/prosody.release new/prosody-0.11.8/prosody.release --- old/prosody-0.11.7/prosody.release 2020-10-01 16:16:52.000000000 +0200 +++ new/prosody-0.11.8/prosody.release 2021-02-15 18:23:35.000000000 +0100 @@ -1 +1 @@ -0.11.7 +0.11.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/spec/net_websocket_frames_spec.lua new/prosody-0.11.8/spec/net_websocket_frames_spec.lua --- old/prosody-0.11.7/spec/net_websocket_frames_spec.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/spec/net_websocket_frames_spec.lua 2021-02-15 16:29:13.000000000 +0100 @@ -32,6 +32,26 @@ ["RSV2"] = false; ["RSV3"] = false; }; + with_mask = { + ["opcode"] = 0; + ["length"] = 5; + ["data"] = "hello"; + ["key"] = " \0 \0"; + ["FIN"] = true; + ["MASK"] = true; + ["RSV1"] = false; + ["RSV2"] = false; + ["RSV3"] = false; + }; + empty_with_mask = { + ["opcode"] = 0; + ["key"] = " \0 \0"; + ["FIN"] = true; + ["MASK"] = true; + ["RSV1"] = false; + ["RSV2"] = false; + ["RSV3"] = false; + }; } describe("build", function () @@ -40,6 +60,8 @@ assert.equal("\0\0", build(test_frames.simple_empty)); assert.equal("\0\5hello", build(test_frames.simple_data)); assert.equal("\128\0", build(test_frames.simple_fin)); + assert.equal("\128\133 \0 \0HeLlO", build(test_frames.with_mask)) + assert.equal("\128\128 \0 \0", build(test_frames.empty_with_mask)) end); end); @@ -49,6 +71,7 @@ assert.same(test_frames.simple_empty, parse("\0\0")); assert.same(test_frames.simple_data, parse("\0\5hello")); assert.same(test_frames.simple_fin, parse("\128\0")); + assert.same(test_frames.with_mask, parse("\128\133 \0 \0HeLlO")); end); end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/spec/util_dbuffer_spec.lua new/prosody-0.11.8/spec/util_dbuffer_spec.lua --- old/prosody-0.11.7/spec/util_dbuffer_spec.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/spec/util_dbuffer_spec.lua 2021-02-15 16:29:13.000000000 +0100 @@ -42,6 +42,7 @@ assert.truthy(b:write("hello world")); assert.truthy(b:discard(6)); assert.equal(5, b:length()); + assert.equal(5, b:len()); assert.equal("world", b:read(5)); end); end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/spec/util_debug_spec.lua new/prosody-0.11.8/spec/util_debug_spec.lua --- old/prosody-0.11.7/spec/util_debug_spec.lua 1970-01-01 01:00:00.000000000 +0100 +++ new/prosody-0.11.8/spec/util_debug_spec.lua 2021-02-15 16:29:13.000000000 +0100 @@ -0,0 +1,93 @@ +local dbg = require "util.debug"; + +describe("util.debug", function () + describe("traceback()", function () + it("works", function () + local tb = dbg.traceback(); + assert.is_string(tb); + end); + end); + describe("get_traceback_table()", function () + it("works", function () + local count = 0; + -- MUST stay in sync with the line numbers of these functions: + local f1_defined, f3_defined = 43, 15; + local function f3(f3_param) --luacheck: ignore 212/f3_param + count = count + 1; + + for i = 1, 2 do + local tb = dbg.get_traceback_table(i == 1 and coroutine.running() or nil, 0); + assert.is_table(tb); + --print(dbg.traceback(), "\n\n\n", require "util.serialization".serialize(tb, { fatal = false, unquoted = true})); + local found_f1, found_f3; + for _, frame in ipairs(tb) do + if frame.info.linedefined == f1_defined then + assert.equal(0, #frame.locals); + assert.equal("f2", frame.upvalues[1].name); + assert.equal("f1_upvalue", frame.upvalues[2].name); + found_f1 = true; + elseif frame.info.linedefined == f3_defined then + assert.equal("f3_param", frame.locals[1].name); + found_f3 = true; + end + end + assert.is_true(found_f1); + assert.is_true(found_f3); + end + end + local function f2() + local f2_local = "hello"; + return f3(f2_local); + end + local f1_upvalue = "upvalue1"; + local function f1() + f2(f1_upvalue); + end + + -- ok/err are caught and re-thrown so that + -- busted gets to handle them in its own way + local ok, err; + local function hook() + debug.sethook(); + ok, err = pcall(f1); + end + + -- Test the traceback is correct in various + -- types of caller environments + + -- From a Lua hook + debug.sethook(hook, "crl", 1); + local a = string.sub("abcdef", 3, 4); + assert.equal("cd", a); + debug.sethook(); + assert.equal(1, count); + + if not ok then + error(err); + end + ok, err = nil, nil; + + -- From a signal handler (C hook) + require "util.signal".signal("SIGUSR1", hook); + require "util.signal".raise("SIGUSR1"); + assert.equal(2, count); + + if not ok then + error(err); + end + ok, err = nil, nil; + + -- Inside a coroutine + local co = coroutine.create(function () + hook(); + end); + coroutine.resume(co); + + if not ok then + error(err); + end + + assert.equal(3, count); + end); + end); +end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/spec/util_stanza_spec.lua new/prosody-0.11.8/spec/util_stanza_spec.lua --- old/prosody-0.11.7/spec/util_stanza_spec.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/spec/util_stanza_spec.lua 2021-02-15 16:29:13.000000000 +0100 @@ -200,6 +200,7 @@ ["number"] = 1234, ["table"] = {}; ["utf8"] = string.char(0xF4, 0x90, 0x80, 0x80); ["nil"] = "nil"; ["boolean"] = true; + ["control characters"] = "\0\1\2\3"; }; for value_type, value in pairs(invalid_names) do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/spec/util_strbitop.lua new/prosody-0.11.8/spec/util_strbitop.lua --- old/prosody-0.11.7/spec/util_strbitop.lua 1970-01-01 01:00:00.000000000 +0100 +++ new/prosody-0.11.8/spec/util_strbitop.lua 2021-02-15 16:29:13.000000000 +0100 @@ -0,0 +1,41 @@ +local strbitop = require "util.strbitop"; +describe("util.strbitop", function () + describe("sand()", function () + it("works", function () + assert.equal(string.rep("Aa", 100), strbitop.sand(string.rep("a", 200), "Aa")); + end); + it("returns empty string if first argument is empty", function () + assert.equal("", strbitop.sand("", "")); + assert.equal("", strbitop.sand("", "key")); + end); + it("returns initial string if key is empty", function () + assert.equal("hello", strbitop.sand("hello", "")); + end); + end); + + describe("sor()", function () + it("works", function () + assert.equal(string.rep("a", 200), strbitop.sor(string.rep("Aa", 100), "a")); + end); + it("returns empty string if first argument is empty", function () + assert.equal("", strbitop.sor("", "")); + assert.equal("", strbitop.sor("", "key")); + end); + it("returns initial string if key is empty", function () + assert.equal("hello", strbitop.sor("hello", "")); + end); + end); + + describe("sxor()", function () + it("works", function () + assert.equal(string.rep("Aa", 100), strbitop.sxor(string.rep("a", 200), " \0")); + end); + it("returns empty string if first argument is empty", function () + assert.equal("", strbitop.sxor("", "")); + assert.equal("", strbitop.sxor("", "key")); + end); + it("returns initial string if key is empty", function () + assert.equal("hello", strbitop.sxor("hello", "")); + end); + end); +end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/dbuffer.lua new/prosody-0.11.8/util/dbuffer.lua --- old/prosody-0.11.7/util/dbuffer.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/dbuffer.lua 2021-02-15 16:29:13.000000000 +0100 @@ -1,5 +1,6 @@ local queue = require "util.queue"; +local s_byte, s_sub = string.byte, string.sub; local dbuffer_methods = {}; local dynamic_buffer_mt = { __index = dbuffer_methods }; @@ -101,7 +102,11 @@ return true; end -function dbuffer_methods:sub(i, j) +-- Normalize i, j into absolute offsets within the +-- front chunk (accounting for front_consumed), and +-- ensure there is enough data in the first chunk +-- to cover any subsequent :sub() or :byte() operation +function dbuffer_methods:_prep_sub(i, j) if j == nil then j = -1; end @@ -118,23 +123,41 @@ j = self._length; end if i > j then - return ""; + return nil; end self:collapse(j); - return self.items:peek():sub(self.front_consumed+1):sub(i, j); + if self.front_consumed > 0 then + i = i + self.front_consumed; + j = j + self.front_consumed; + end + + return i, j; +end + +function dbuffer_methods:sub(i, j) + i, j = self:_prep_sub(i, j); + if not i then + return ""; + end + return s_sub(self.items:peek(), i, j); end function dbuffer_methods:byte(i, j) i = i or 1; j = j or i; - return string.byte(self:sub(i, j), 1, -1); + i, j = self:_prep_sub(i, j); + if not i then + return; + end + return s_byte(self.items:peek(), i, j); end function dbuffer_methods:length() return self._length; end +dbuffer_methods.len = dbuffer_methods.length; -- strings have :len() dynamic_buffer_mt.__len = dbuffer_methods.length; -- support # operator function dbuffer_methods:collapse(bytes) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/debug.lua new/prosody-0.11.8/util/debug.lua --- old/prosody-0.11.7/util/debug.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/debug.lua 2021-02-15 16:29:13.000000000 +0100 @@ -104,7 +104,7 @@ levels[(level-start_level)+1] = { level = level; info = info; - locals = get_locals_table(thread, level+(thread and 0 or 1)); + locals = get_locals_table(thread, level+1); upvalues = get_upvalues_table(info.func); }; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/dependencies.lua new/prosody-0.11.8/util/dependencies.lua --- old/prosody-0.11.7/util/dependencies.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/dependencies.lua 2021-02-15 16:29:13.000000000 +0100 @@ -90,7 +90,7 @@ }, "SSL/TLS support will not be available"); end - local bit = _G.bit32 or softreq"bit"; + local bit = softreq"bit" or softreq"bit32"; if not bit then missingdep("lua-bitops", { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/interpolation.lua new/prosody-0.11.8/util/interpolation.lua --- old/prosody-0.11.7/util/interpolation.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/interpolation.lua 2021-02-15 16:29:13.000000000 +0100 @@ -43,11 +43,11 @@ end end if funcs then - while value ~= nil and opt == '|' do + while opt == '|' do local f; f, raw, opt, e = s_match(block, "^([%a_][%w_.]*)(!?)(%p?)()", e); f = funcs[f]; - if f then value = f(value); end + if value ~= nil and f then value = f(value); end end end if opt == '#' or opt == '%' then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/promise.lua new/prosody-0.11.8/util/promise.lua --- old/prosody-0.11.7/util/promise.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/promise.lua 2021-02-15 16:29:13.000000000 +0100 @@ -78,7 +78,7 @@ local p = setmetatable({ _state = "pending", _next = next_pending, _pending_on_fulfilled = {}, _pending_on_rejected = {} }, promise_mt); if f then local resolve, reject = new_resolve_functions(p); - local ok, ret = pcall(f, resolve, reject); + local ok, ret = xpcall(f, debug.traceback, resolve, reject); if not ok and p._state == "pending" then reject(ret); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/stanza.lua new/prosody-0.11.8/util/stanza.lua --- old/prosody-0.11.7/util/stanza.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/stanza.lua 2021-02-15 16:29:13.000000000 +0100 @@ -45,6 +45,10 @@ local stanza_mt = { __name = "stanza" }; stanza_mt.__index = stanza_mt; +local function valid_xml_cdata(str, attr) + return not s_find(str, attr and "[^\1\9\10\13\20-~\128-\247]" or "[^\9\10\13\20-~\128-\247]"); +end + local function check_name(name, name_type) if type(name) ~= "string" then error("invalid "..name_type.." name: expected string, got "..type(name)); @@ -52,6 +56,8 @@ error("invalid "..name_type.." name: empty string"); elseif s_find(name, "[<>& '\"]") then error("invalid "..name_type.." name: contains invalid characters"); + elseif not valid_xml_cdata(name, name_type == "attribute") then + error("invalid "..name_type.." name: contains control characters"); elseif not valid_utf8(name) then error("invalid "..name_type.." name: contains invalid utf8"); end @@ -60,6 +66,8 @@ local function check_text(text, text_type) if type(text) ~= "string" then error("invalid "..text_type.." value: expected string, got "..type(text)); + elseif not valid_xml_cdata(text, false) then + error("invalid "..text_type.." value: contains control characters"); elseif not valid_utf8(text) then error("invalid "..text_type.." value: contains invalid utf8"); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util/timer.lua new/prosody-0.11.8/util/timer.lua --- old/prosody-0.11.7/util/timer.lua 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util/timer.lua 2021-02-15 16:29:13.000000000 +0100 @@ -15,6 +15,7 @@ local tostring = tostring; local xpcall = require "util.xpcall".xpcall; local math_max = math.max; +local pairs = pairs; local _ENV = nil; -- luacheck: std none @@ -29,6 +30,7 @@ local function _traceback_handler(err) log("error", "Traceback[timer]: %s", debug_traceback(tostring(err), 2)); end local function _on_timer(now) local peek; + local readd; while true do peek = h:peek(); if peek == nil or peek > now then break; end @@ -38,11 +40,22 @@ --item(now, id, _param); local success, err = xpcall(callback, _traceback_handler, now, id, param); if success and type(err) == "number" then - h:insert(callback, err + now, id); -- re-add + if readd then + readd[id] = { callback, err + now }; + else + readd = { [id] = { callback, err + now } }; + end params[id] = param; end end + if readd then + for id,timer in pairs(readd) do + h:insert(timer[1], timer[2], id); + end + peek = h:peek(); + end + if peek ~= nil and _active_timers > 1 and peek == next_time then -- Another instance of _on_timer already set next_time to the same value, -- so it should be safe to not renew this timer event diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util-src/GNUmakefile new/prosody-0.11.8/util-src/GNUmakefile --- old/prosody-0.11.7/util-src/GNUmakefile 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util-src/GNUmakefile 2021-02-15 16:29:13.000000000 +0100 @@ -7,7 +7,7 @@ TARGET?=../util/ ALL=encodings.so hashes.so net.so pposix.so signal.so table.so \ - ringbuffer.so time.so poll.so compat.so + ringbuffer.so time.so poll.so compat.so strbitop.so ifdef RANDOM ALL+=crand.so diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util-src/makefile new/prosody-0.11.8/util-src/makefile --- old/prosody-0.11.7/util-src/makefile 2020-05-31 22:39:34.000000000 +0200 +++ new/prosody-0.11.8/util-src/makefile 2021-02-15 16:29:13.000000000 +0100 @@ -6,7 +6,7 @@ TARGET?=../util/ ALL=encodings.so hashes.so net.so pposix.so signal.so table.so \ - ringbuffer.so time.so poll.so compat.so + ringbuffer.so time.so poll.so compat.so strbitop.so .ifdef $(RANDOM) ALL+=crand.so diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.11.7/util-src/strbitop.c new/prosody-0.11.8/util-src/strbitop.c --- old/prosody-0.11.7/util-src/strbitop.c 1970-01-01 01:00:00.000000000 +0100 +++ new/prosody-0.11.8/util-src/strbitop.c 2021-02-15 16:29:13.000000000 +0100 @@ -0,0 +1,91 @@ +/* + * This project is MIT licensed. Please see the + * COPYING file in the source package for more information. + * + * Copyright (C) 2016 Kim Alvefur + */ + +#include <lua.h> +#include <lauxlib.h> + +#if (LUA_VERSION_NUM == 501) +#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) +#endif + +/* TODO Deduplicate code somehow */ + +int strop_and(lua_State *L) { + luaL_Buffer buf; + size_t a, b, i; + const char *str_a = luaL_checklstring(L, 1, &a); + const char *str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] & str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +int strop_or(lua_State *L) { + luaL_Buffer buf; + size_t a, b, i; + const char *str_a = luaL_checklstring(L, 1, &a); + const char *str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] | str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +int strop_xor(lua_State *L) { + luaL_Buffer buf; + size_t a, b, i; + const char *str_a = luaL_checklstring(L, 1, &a); + const char *str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] ^ str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +LUA_API int luaopen_util_strbitop(lua_State *L) { + luaL_Reg exports[] = { + { "sand", strop_and }, + { "sor", strop_or }, + { "sxor", strop_xor }, + { NULL, NULL } + }; + + lua_newtable(L); + luaL_setfuncs(L, exports, 0); + return 1; +}
