regex: -G<pattern> feeds a non NUL-terminated string to regexec() and fails
commitdb5dfa331480650c1f889db3cb32a0272dc72ec6
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 21 Sep 2016 18:23:22 +0000 (21 20:23 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 21 Sep 2016 20:56:15 +0000 (21 13:56 -0700)
treebad1521b8797ecd860f51c5401a42e9abacea089
parent0b65a8dbdb38962e700ee16776a3042beb489060
regex: -G<pattern> feeds a non NUL-terminated string to regexec() and fails

When our pickaxe code feeds file contents to regexec(), it implicitly
assumes that the file contents are read into implicitly NUL-terminated
buffers (i.e. that we overallocate by 1, appending a single '\0').

This is not so.

In particular when the file contents are simply mmap()ed, we can be
virtually certain that the buffer is preceding uninitialized bytes, or
invalid pages.

Note that the test we add here is known to be flakey: we simply cannot
know whether the byte following the mmap()ed ones is a NUL or not.

Typically, on Linux the test passes. On Windows, it fails virtually
every time due to an access violation (that's a segmentation fault for
you Unix-y people out there). And Windows would be correct: the
regexec() call wants to operate on a regular, NUL-terminated string,
there is no NUL in the mmap()ed memory range, and it is undefined
whether the next byte is even legal to access.

When run with --valgrind it demonstrates quite clearly the breakage, of
course.

Being marked with `test_expect_failure`, this test will sometimes be
declare "TODO fixed", even if it only passes by mistake.

This test case represents a Minimal, Complete and Verifiable Example of
a breakage reported by Chris Sidi.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t4062-diff-pickaxe.sh [new file with mode: 0755]