]> git.draconx.ca Git - cdecl99.git/commit
libcdecl: Work around GNU libc snprintf bug.
authorNick Bowler <nbowler@draconx.ca>
Fri, 28 Jul 2023 04:00:12 +0000 (00:00 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 28 Jul 2023 04:20:58 +0000 (00:20 -0400)
commit8d1fb21fe111eba2b54579d5115017f40d0d949c
tree6182d62d244a0a2324a8c3e1d9e4b584f5d01141
parent39aa5b577e6b01f53ed68e7851dcd982e0bb8015
libcdecl: Work around GNU libc snprintf bug.

Apparently, with GNU libc (even contemporary versions), you cannot simply
pass an arbitrarily-large length.  It appears that glibc internally adds
the provided length to the provided destination pointer, and if that
calculation overflows, then the actual output is silently truncated.

I believe this to be an error in glibc; the only thing the specification
for snprintf says about the length n is that output characters beyond
the "n-1st" are discarded, which doesn't imply that it is invalid to
for a program to pass large length values.  But it doesn't really
matter, we just have to deal with this behaviour since it exists.

This only affects the parser syntax error path, since 41ff7ec97691
("libcdecl: Simplify Bison error message reporting.") changed that to
use cdecl__strlcpy with a large size (INT_MAX).  The normal output path
always passes an actual buffer length.  The bison-generated syntax error
code does not track buffer lengths, but it does ensure the buffer is
large enough so we can use strlen to infer a suitable length.

A new test case is added to sortof directly test the issue, without
the fix it reliably fails for me on 32-bit x86, as the stack above 2G.
The invalid character test also fails because of this issue, but for a
subtly different reason.
src/parse.y
tests/general.at