If there is no '}' in a ${variable} placeholder, the "varname" buffer
will not be NUL-terminated, resulting in various valgrind splats:
==2749814== Conditional jump or move depends on uninitialised value(s)
==2749814== at 0x484ED28: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2749814== by 0x48FED30: __vfprintf_internal (vfprintf-internal.c:1517)
==2749814== by 0x4910499: __vsnprintf_internal (vsnprintf.c:114)
==2749814== by 0x48609AC: vsnprintf (stdio2.h:85)
==2749814== by 0x48609AC: pkgconf_trace (client.c:384)
==2749814== by 0x4864D6A: pkgconf_tuple_parse (tuple.c:358)
==2749814== by 0x48643B3: pkgconf_fragment_parse (fragment.c:680)
We can simplify this code by detecting when it is time to terminate the
loop and then always NUL-terminating the result.
It is always safe to do this final NUL write because "vend" always points
to the last byte of the buffer and we know that "vptr" will never go beyond
it.
Test case:
echo 'Cflags: -I${includedir' > test.pc
LD_LIBRARY_PATH=.libs PKG_CONFIG_PATH=. valgrind ./.libs/pkgconf --cflags test
Fixes: 5eb9cae0091e (libpkgconf: tuple: fix out of boundary write)
Ah, sorry, you're right; looks like the issue has been there since
commit ba1c41eb. Feel free to drop the Fixes: line.
We could also change the patch title to something like
libpkgconf: tuple: fix NUL termination on missing '}'
or whatever the maintainer would prefer :-)
This implies that looking for a closing bracket stops when the
internal buffer capacity is reached.
If something like "${.....${test}" is written, it can happen
that "test" is actually resolved, while with the current code,
the whole expression between first { and first } is considered.
This means that very long illegal expressions would be interpreted
differently.
I think it's best to still iterate until the closing bracket or
end of string is reached.
Tobias