xpath BUGFIX print_expr_str undefined behavior (#2126)
clang 16 with ASAN and UBSAN flag this as UB because it's performing
pointer arithmetic on a NULL pointer, which is not allowed in C.
The test suite of libyang-cpp triggers this behavior:
2/4 Test #1: test_context .....................***Failed 0.77 sec
libyang[0]: Unexpected end-of-input. (path: Line number 1.)
libyang[0]: Data model "invalid" not found in local searchdirs.
libyang[0]: Loading "invalid" module failed.
libyang[0]: Feature "nonexisting" not found in module "mod1".
libyang[0]: Data model "doesnt-exist" not found in local searchdirs.
libyang[0]: Loading "doesnt-exist" module failed.
/home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/xpath.c:239:24: runtime error: applying zero offset to null pointer
#0 0x7f4054b4d168 in print_expr_str /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/xpath.c:239:24
#1 0x7f4054b2ba16 in print_expr_struct_debug /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/xpath.c:276:9
#2 0x7f4054b27209 in lyxp_expr_parse /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/xpath.c:3216:5
#3 0x7f40543582ab in ly_path_parse /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/path.c:339:5
#4 0x7f405441c8d4 in lyd_find_path /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/tree_data.c:3028:11
#5 0x7f4055751848 in libyang::DataNode::findPath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, libyang::OutputNodes) const /home/ci/src/cesnet-gerrit-public/CzechLight/libyang-cpp/src/DataNode.cpp:220:16
#6 0x5424d5 in DOCTEST_ANON_FUNC_2() /home/ci/src/cesnet-gerrit-public/CzechLight/libyang-cpp/tests/context.cpp:346:9
#7 0x5ffbf7 in doctest::Context::run() /home/ci/target/include/doctest/doctest.h:7007:21
#8 0x60556d in main /home/ci/target/include/doctest/doctest.h:7085:71
#9 0x7f4055048b49 in __libc_start_call_main /usr/src/debug/glibc-2.37-1.fc38.x86_64/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#10 0x7f4055048c0a in __libc_start_main@GLIBC_2.2.5 /usr/src/debug/glibc-2.37-1.fc38.x86_64/csu/../csu/libc-start.c:360:3
#11 0x4450f4 in _start (/home/ci/build/CzechLight/libyang-cpp/test_context+0x4450f4) (BuildId: b2cbc6b91e2c885110ddbf157ff7a19e41ed0306)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/ci/src/cesnet-gerrit-public/github/CESNET/libyang/src/xpath.c:239:24 in
I'm getting this on Fedora 38 and on Arch, but for some reason I cannot
seem to hit the original issue on NixOS. Strange, but it's an UB anyway.
Fixes: 1696178edf8121ab680baa121fa2b851d1a78cd8 xpath UPDATE do not use memstream
diff --git a/src/xpath.c b/src/xpath.c
index 309150b..37e8d1e 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -236,7 +236,7 @@
va_start(ap, format);
/* try to append the string */
- p = vsnprintf(*str + *used, *size - *used, format, ap);
+ p = vsnprintf(*str ? *str + *used : NULL, *size - *used, format, ap);
if ((unsigned)p >= *size - *used) {
/* realloc */