In both the _WIN32 and the POSIX variant of UTIL_prepareFileList(),
the buffer-growth branch computed
*bufEnd = *bufStart + newListSize;
before checking whether UTIL_realloc() succeeded. UTIL_realloc frees
the old block and returns NULL on failure, so the statement performs
pointer arithmetic on a null pointer (undefined behavior, C17 6.5.6)
and leaves *bufEnd holding a bogus non-NULL extent.
Found via cppcheck nullPointerArithmeticRedundantCheck warnings
(util.h:411 and util.h:468); confirmed end-to-end by building the real
lz4 CLI with clang -fsanitize=pointer-overflow and failing the growth
realloc via LD_PRELOAD: 'util.h:468:37: runtime error: applying
non-zero offset 16384 to null pointer'. With this patch the same run
completes with no sanitizer report.
This allows us to get the file size even when the input file is passed
via stdin. This fixes `--content-size` not working in situations like
$ lz4 -v --content-size < /tmp/test > /tmp/test.lz4
Warning : cannot determine input content size
With this change, it works.
Also helps with #904.
Previous method would produce too many time() invocations,
becoming a significant fraction of workload measured.
The new strategy is to use time() only once per batch,
and dynamically resize batch size so that each round lasts approximately 1 second.
This only matters for small inputs.
Measurement for large files (such as silesia.tar) are much less impacted
(though decoding speed is so fast that even medium-size files will notice an improvement).
The timer used was only accurate up to 0.01 seconds. This timer is accurate up to 1 ns.
It is a monotonic timer that measures the real time difference, not on CPU time.
Copied the benchmark code from 6ab4d5e904