swupdate_dwl_url() is part of libswupdate, but SET_DELTA_URL support
started using strlcpy() there. The helper is provided by core/strlcpy.o,
which is not linked into libswupdate, so configurations that build the
shared IPC client library fail with an undefined reference.
Replace it with the same memset plus strncpy pattern already used by the
other IPC helper setters, and add a focused regression test for
swupdate_dwl_url().
Fixes: 89ee5291ba3c ("Add IPC to send a list of URL as sources")
Signed-off-by: Aviv Daum <
aviv...@gmail.com>
---
ipc/network_ipc-if.c | 13 +++----
test/Makefile | 7 +++-
test/test_network_ipc_if.c | 71 ++++++++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 7 deletions(-)
create mode 100644 test/test_network_ipc_if.c
diff --git a/ipc/network_ipc-if.c b/ipc/network_ipc-if.c
index 732f3ad5..5cc3550c 100644
--- a/ipc/network_ipc-if.c
+++ b/ipc/network_ipc-if.c
@@ -413,12 +413,13 @@ int swupdate_dwl_url (const char *artifact_name, const char *url)
msg.magic = IPC_MAGIC;
msg.type = SET_DELTA_URL;
- strlcpy(msg.data.dwl_url.filename,
- artifact_name,
- sizeof(msg.data.dwl_url.filename) - 1);
- strlcpy(msg.data.dwl_url.url,
- url,
- sizeof(msg.data.dwl_url.url) - 1);
+ strncpy(msg.data.dwl_url.filename,
+ artifact_name,
+ sizeof(msg.data.dwl_url.filename) - 1);
+ strncpy(msg.data.dwl_url.url,
+ url,
+ sizeof(msg.data.dwl_url.url) - 1);
+
return ipc_send_cmd(&msg);
}
diff --git a/test/Makefile b/test/Makefile
index c59a9c89..7fa02dbd 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -29,8 +29,11 @@ tests-$(CONFIG_SURICATTA_HAWKBIT) += test_json
tests-$(CONFIG_SURICATTA_HAWKBIT) += test_server_hawkbit
tests-$(CONFIG_MONGOOSE) += test_mongoose_upload
tests-y += test_util
+tests-y += test_network_ipc_if
tests-$(CONFIG_CFI) += test_flash_handler
+test_network_ipc_if-extra-objs := $(objtree)/ipc/network_ipc-if.o
+
ccflags-y += -I$(src)/../
TARGETS = $(addprefix $(obj)/, $(tests-y))
@@ -64,7 +67,7 @@ quiet_cmd_linktestexe = LD $(basename $@)
"$(CC)" \
"$(KBUILD_CFLAGS)" \
"$(LDFLAGS) $(EXTRA_LDFLAGS) $(LDMOCKS)" \
- "$(basename $@).o $(subst core/built-in.o,core/built-in.o.tmp,$(SWOBJS))" \
+ "$(basename $@).o $($(notdir $(basename $@))-extra-objs) $(subst core/built-in.o,core/built-in.o.tmp,$(SWOBJS))" \
"$(SWLIBS)" \
"$(LDLIBS) cmocka"
@@ -87,6 +90,8 @@ endif
$(objtree)/core/built-in.o.tmp: $(objtree)/core/built-in.o
$(Q)$(STRIP) -N main -o $(objtree)/core/built-in.o.tmp $(objtree)/core/built-in.o
+$(obj)/test_network_ipc_if.lnk: $(test_network_ipc_if-extra-objs)
+
$(obj)/%.lnk: $(obj)/%.o $(objtree)/core/built-in.o.tmp
$(Q)$(call cmd,linktestexe)
diff --git a/test/test_network_ipc_if.c b/test/test_network_ipc_if.c
new file mode 100644
index 00000000..7fbab0c4
--- /dev/null
+++ b/test/test_network_ipc_if.c
@@ -0,0 +1,71 @@
+// SPDX-FileCopyrightText: 2026 Aviv Daum <
aviv...@gmail.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <cmocka.h>
+
+#include "network_ipc.h"
+
+static ipc_message last_msg;
+
+extern int __real_ipc_send_cmd(ipc_message *msg);
+int __wrap_ipc_send_cmd(ipc_message *msg);
+int __wrap_ipc_send_cmd(ipc_message *msg)
+{
+ last_msg = *msg;
+ return 0;
+}
+
+static int network_ipc_if_setup(void **state)
+{
+ (void)state;
+ memset(&last_msg, 0, sizeof(last_msg));
+ return 0;
+}
+
+static void test_swupdate_dwl_url_populates_message(void **state)
+{
+ (void)state;
+
+ assert_int_equal(swupdate_dwl_url("artifact.swu", "
https://example.invalid/a.swu"), 0);
+ assert_int_equal(last_msg.magic, IPC_MAGIC);
+ assert_int_equal(last_msg.type, SET_DELTA_URL);
+ assert_string_equal(last_msg.data.dwl_url.filename, "artifact.swu");
+ assert_string_equal(last_msg.data.dwl_url.url, "
https://example.invalid/a.swu");
+}
+
+static void test_swupdate_dwl_url_truncates_and_terminates(void **state)
+{
+ char filename[400];
+ char url[1200];
+
+ (void)state;
+
+ memset(filename, 'f', sizeof(filename) - 1);
+ filename[sizeof(filename) - 1] = '\0';
+ memset(url, 'u', sizeof(url) - 1);
+ url[sizeof(url) - 1] = '\0';
+
+ assert_int_equal(swupdate_dwl_url(filename, url), 0);
+ assert_int_equal(last_msg.data.dwl_url.filename[sizeof(last_msg.data.dwl_url.filename) - 1], '\0');
+ assert_int_equal(last_msg.data.dwl_url.url[sizeof(last_msg.data.dwl_url.url) - 1], '\0');
+ assert_int_equal(strlen(last_msg.data.dwl_url.filename), sizeof(last_msg.data.dwl_url.filename) - 1);
+ assert_int_equal(strlen(last_msg.data.dwl_url.url), sizeof(last_msg.data.dwl_url.url) - 1);
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_swupdate_dwl_url_populates_message),
+ cmocka_unit_test(test_swupdate_dwl_url_truncates_and_terminates),
+ };
+
+ return cmocka_run_group_tests_name("network_ipc_if", tests,
+ network_ipc_if_setup, NULL);
+}
--
2.34.1