fragment_quote adds quotation to fragments if needed. It allocates a
buffer and grows it as needed.
Unfortunately the dst pointer is not updated after a realloc, which
means that dst still points into the old memory area. Further writing
characters into that area leads to out of boundy writes.
Proof of concept:
$ cat > poc.pc << EOF
Name: poc
Description: poc
Version: 1
CFlags: -Ia
CFlags: -I%%%%%%%%%%%%%%%%%%%%b
CFlags: -I%%%%%%%%%%%%%%%%%%%%c
CFlags: -Id
EOF
$ pkgconf --cflags poc.pc
Most reliable attempt is to compile pkgconf with address sanitizer,
but this file should lead to an abort on a glibc system due to modified
chunk pointers (tested with Linux on amd64).
But since this is undefined behaviour, it depends on system details.
Parsing a fragment which consists only of a single dash leads to
an out of boundary read. It duplicates the following entry which
is not expected behaviour if another fragment follows.
Proof of concept:
$ cat > poc.pc << "EOF"
Name: poc
Description: poc
Version: 1
Cflags: - -I/somewhere
EOF
$ PKG_CONFIG_PATH=. pkgconf --cflags poc
-I/somewhere -I/somewhere
If - is the last entry, it leads to an out of boundary read, which is
easy to see if pkgconf is compiled with address sanitizer.
According to
https://docs.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file
backslashes (with slashes) are a path separator, hence must no be
considered as an escape code.
The first fix, in argvsplit.c, disables this. But because of fragment_quote(),
the backslashes are doubled. Hence the second fix in fragment.c
With this pc file :
prefix=C:/Documents/msys2/opt/efl_64
libdir=${prefix}/lib
includedir=${prefix}/include
Name: eina
Description: efl: eina
Version: 1.24.99
Requires.private: iconv
Libs: -L${libdir} -leina -pthread -levil
Libs.private: -lpsapi -lole32 -lws2_32 -lsecur32 -luuid -lregex -lm
Cflags:-I${includedir}/eina-1 -I${includedir}/efl-1
-I${includedir}/eina-1/eina -pthread
pkgconf.exe --cflags eina
returns :
-IC:\Documents\msys2\opt\efl_64/include/eina-1
-IC:\Documents\msys2\opt\efl_64/include/efl-1
-IC:\Documents\msys2\opt\efl_64/include/eina-1/eina -pthread
-DWINICONV_CONST= -IC:\Documents\msys2\opt\ewpi_64/include
we now use POSIX-style quoting for all fragments. it is our belief that this is the
most optimal behaviour for portability, because all POSIX-compliant tools require
single-quotes to be considered as literal (closes#153).
because of this, we are able to remove some hacks on the lexer side which were there
to simulate pkg-config quoting, but were basically utterly wrong (closes#139).