changeset 14186:d975d280baec

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Mon, 25 May 2026 19:01:23 +0100
parents 4f4c346e4f39 (current diff) e23b9651145d (diff)
children 4f12f98c2ec1
files plugins/mod_carbons.lua util-src/crypto.c util-src/pposix.c util/jsonschema.lua util/pubsub.lua
diffstat 14 files changed, 68 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/net/http/parser.lua	Tue May 19 19:27:43 2026 +0100
+++ b/net/http/parser.lua	Mon May 25 19:01:23 2026 +0100
@@ -4,13 +4,17 @@
 local urldecode = require "prosody.util.http".urldecode;
 local dbuffer = require "prosody.util.dbuffer";
 
+
+-- This is a basic check, and does *not* fully prevent path traversal (CWE-22).
+-- If the path will be mapped to a filesystem, further processing and checks
+-- are needed for safety and compliance. This is handled by net.http.files.
 local function preprocess_path(path)
 	path = urldecode((path:gsub("//+", "/")));
 	if path:sub(1,1) ~= "/" then
 		path = "/"..path;
 	end
 	local level = 0;
-	for component in path:gmatch("([^/]+)/") do
+	for component in path:gmatch("([^/]+)") do
 		if component == ".." then
 			level = level - 1;
 		elseif component ~= "." then
--- a/net/stun.lua	Tue May 19 19:27:43 2026 +0100
+++ b/net/stun.lua	Mon May 25 19:01:23 2026 +0100
@@ -185,7 +185,7 @@
 		local attr_type, attr_len = struct.unpack(">I2I2", attr_hdr); --luacheck: ignore 211/attr_type
 		if attr_len == 0 then
 			table.insert(self.attributes, attr_hdr);
-			pos = pos + 20;
+			pos = pos + 4;
 		else
 			local data = bytes:sub(pos + 4, pos + 3 + attr_len);
 			assert(#data == attr_len, "packet truncated in attribute value");
--- a/plugins/mod_carbons.lua	Tue May 19 19:27:43 2026 +0100
+++ b/plugins/mod_carbons.lua	Mon May 25 19:01:23 2026 +0100
@@ -141,7 +141,7 @@
 				-- Create the carbon copy and wrap it as per the Stanza Forwarding XEP
 				local copy = st.clone(stanza);
 				if c2s and not orig_to then
-					stanza.attr.to = bare_from;
+					copy.attr.to = bare_from;
 				end
 				copy.attr.xmlns = "jabber:client";
 				carbon = st.message{ from = bare_jid, type = orig_type, }
--- a/plugins/mod_register_ibr.lua	Tue May 19 19:27:43 2026 +0100
+++ b/plugins/mod_register_ibr.lua	Mon May 25 19:01:23 2026 +0100
@@ -11,7 +11,7 @@
 local dataform_new = require "prosody.util.dataforms".new;
 local usermanager_user_exists  = require "prosody.core.usermanager".user_exists;
 local usermanager_create_user_with_role  = require "prosody.core.usermanager".create_user_with_role;
-local usermanager_set_password = require "prosody.core.usermanager".create_user;
+local usermanager_set_password = require "prosody.core.usermanager".set_password;
 local usermanager_delete_user  = require "prosody.core.usermanager".delete_user;
 local nodeprep = require "prosody.util.encodings".stringprep.nodeprep;
 local util_error = require "prosody.util.error";
--- a/spec/util_ringbuffer_spec.lua	Tue May 19 19:27:43 2026 +0100
+++ b/spec/util_ringbuffer_spec.lua	Mon May 25 19:01:23 2026 +0100
@@ -35,6 +35,51 @@
 		end);
 	end);
 
+	describe(":find", function ()
+		local function test_find(b, str, expected)
+			if expected ~= nil then
+				assert.equal(expected, b:find(str));
+			else
+				assert.is_nil(b:find(str));
+			end
+		end
+
+		it("works", function ()
+			local b = rb.new();
+			assert.truthy(b:write("hello world"));
+			test_find(b, "world", 7);
+		end);
+
+		it("works across wraps", function ()
+			local b = rb.new(5);
+			assert.truthy(b:write("12345"));
+			assert.equal("123", b:read(3));
+			assert.truthy(b:write("678"));
+			test_find(b, "45678", 1);
+			test_find(b, "567", 2);
+			test_find(b, "56", 2);
+			test_find(b, "5", 2);
+			test_find(b, "6", 3);
+			test_find(b, "7", 4);
+			test_find(b, "8", 5);
+			test_find(b, "9", nil);
+		end);
+
+		it("no match when the needle is larger than the buffer", function ()
+			for i = 5, 11 do
+				local b = rb.new(i);
+				assert.truthy(b:write("hello"));
+				test_find(b, "hello world", nil);
+			end
+		end);
+
+		it("no match when the needle is an empty string", function ()
+			local b = rb.new(5);
+			assert.truthy(b:write("hello"));
+			test_find(b, "", nil);
+		end);
+	end);
+
 	describe(":sub", function ()
 		-- Helper function to compare buffer:sub() with string:sub()
 		local function test_sub(b, x, y)
--- a/util-src/crypto.c	Tue May 19 19:27:43 2026 +0100
+++ b/util-src/crypto.c	Mon May 25 19:01:23 2026 +0100
@@ -133,7 +133,7 @@
 	luaL_Buffer sigbuf;
 
 	size_t msg_len;
-	const unsigned char* msg = (unsigned char*)lua_tolstring(L, 2, &msg_len);
+	const unsigned char* msg = (unsigned char*)luaL_checklstring(L, 2, &msg_len);
 
 	size_t sig_len;
 	unsigned char *sig = NULL;
@@ -151,16 +151,13 @@
 		return 1;
 	}
 
-	// COMPAT w/ Lua 5.1
-	luaL_buffinit(L, &sigbuf);
-	sig = memset(luaL_prepbuffer(&sigbuf), 0, sig_len);
+	sig = (unsigned char *)luaL_buffinitsize(L, &sigbuf, sig_len);
 
 	if(EVP_DigestSign(md_ctx, sig, &sig_len, msg, msg_len) != 1) {
 		lua_pushnil(L);
 	}
 	else {
-		luaL_addsize(&sigbuf, sig_len);
-		luaL_pushresult(&sigbuf);
+		luaL_pushresultsize(&sigbuf, sig_len);
 		return 1;
 	}
 
--- a/util-src/poll.c	Tue May 19 19:27:43 2026 +0100
+++ b/util-src/poll.c	Mon May 25 19:01:23 2026 +0100
@@ -139,7 +139,7 @@
 #endif
 #ifdef USE_SELECT
 
-	if(fd > FD_SETSIZE) {
+	if(fd >= FD_SETSIZE) {
 		luaL_pushfail(L);
 		lua_pushstring(L, strerror(EBADF));
 		lua_pushinteger(L, EBADF);
--- a/util-src/pposix.c	Tue May 19 19:27:43 2026 +0100
+++ b/util-src/pposix.c	Mon May 25 19:01:23 2026 +0100
@@ -169,6 +169,7 @@
 	"local7",
 	"lpr",
 	"mail",
+	"news",
 	"syslog",
 	"user",
 	"uucp",
--- a/util-src/ringbuffer.c	Tue May 19 19:27:43 2026 +0100
+++ b/util-src/ringbuffer.c	Mon May 25 19:01:23 2026 +0100
@@ -82,7 +82,7 @@
 	size_t i, j;
 	int m;
 
-	if(b->rpos == b->wpos) { /* empty */
+	if(l > b->blen || l == 0) { /* needle is too large or too small */
 		return 0;
 	}
 
@@ -99,7 +99,7 @@
 				}
 
 			if(m) {
-				return i + l;
+				return i + 1;
 			}
 		}
 	}
--- a/util-src/signal.c	Tue May 19 19:27:43 2026 +0100
+++ b/util-src/signal.c	Mon May 25 19:01:23 2026 +0100
@@ -498,9 +498,10 @@
 		return 1;
 	}
 
-	for(int i = signalfd_num; i > 0; i--) {
+	for(int i = signalfd_num - 1; i >= 0; i--) {
 		if(signalfds[i].fd == sfd->fd) {
-			signalfds[i] = signalfds[signalfd_num--];
+			signalfds[i] = signalfds[--signalfd_num];
+			break;
 		}
 	}
 
--- a/util/dataforms.lua	Tue May 19 19:27:43 2026 +0100
+++ b/util/dataforms.lua	Mon May 25 19:01:23 2026 +0100
@@ -252,7 +252,7 @@
 				err[#err+1] = ("Invalid JID: " .. raw_value);
 			end
 		end
-		if #result > 0 then
+		if #result > 0 or #err > 0 then
 			return result, (#err > 0 and t_concat(err, "\n") or nil);
 		elseif required then
 			return nil, "Required value missing";
--- a/util/datamanager.lua	Tue May 19 19:27:43 2026 +0100
+++ b/util/datamanager.lua	Mon May 25 19:01:23 2026 +0100
@@ -668,7 +668,7 @@
 					if lfs.attributes(getpath(username, host, store_name, typ), "mode") then
 						return store_name;
 					end
-				elseif lfs.attributes(node, "mode") == "file" then
+				elseif lfs.attributes(store_dir..node, "mode") == "file" then
 					local file, ext = node:match("^(.*)%.([dalist]+)$");
 					if ext == typ then
 						return decode(file)
--- a/util/jsonschema.lua	Tue May 19 19:27:43 2026 +0100
+++ b/util/jsonschema.lua	Mon May 25 19:01:23 2026 +0100
@@ -121,7 +121,7 @@
 	end
 
 	if type(data) == "number" then
-		if schema.multipleOf and (data == 0 or data % schema.multipleOf ~= 0) then
+		if schema.multipleOf and data ~= 0 and data % schema.multipleOf ~= 0 then
 			table.insert(errs, mkerr(sloc .. "/luaPattern", iloc, "not a multiple"))
 			return false, errs
 		end
--- a/util/pubsub.lua	Tue May 19 19:27:43 2026 +0100
+++ b/util/pubsub.lua	Mon May 25 19:01:23 2026 +0100
@@ -355,7 +355,7 @@
 			return ok, err;
 		end
 	elseif jid_sub and not self:may(node, jid, "be_subscribed") then
-		local ok, err = self:add_subscription(node, true, jid);
+		local ok, err = self:remove_subscription(node, true, jid);
 		if not ok then
 			return ok, err;
 		end
@@ -662,7 +662,7 @@
 	if self.config.nodestore then
 		local ok, err = delete_node_in_store(self, node);
 		if not ok then
-			self.nodes[node] = nil;
+			self.nodes[node] = node_obj;
 			return ok, err;
 		end
 	end