diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2016-09-21 20:24:04 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-09-21 13:56:15 -0700 |
commit | 2f8952250a84313b74f96abb7b035874854cf202 (patch) | |
tree | 264e571b5f86d2a4cf01117630089ac3c94e97fe | |
parent | db5dfa331480650c1f889db3cb32a0272dc72ec6 (diff) | |
download | git-2f8952250a84313b74f96abb7b035874854cf202.tar.gz |
regex: add regexec_buf() that can work on a non NUL-terminated string
We just introduced a test that demonstrates that our sloppy use of
regexec() on a mmap()ed area can result in incorrect results or even
hard crashes.
So what we need to fix this is a function that calls regexec() on a
length-delimited, rather than a NUL-terminated, string.
Happily, there is an extension to regexec() introduced by the NetBSD
project and present in all major regex implementation including
Linux', MacOSX' and the one Git includes in compat/regex/: by using
the (non-POSIX) REG_STARTEND flag, it is possible to tell the
regexec() function that it should only look at the offsets between
pmatch[0].rm_so and pmatch[0].rm_eo.
That is exactly what we need.
Since support for REG_STARTEND is so widespread by now, let's just
introduce a helper function that always uses it, and tell people
on a platform whose regex library does not support it to use the
one from our compat/regex/ directory.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | git-compat-util.h | 13 |
2 files changed, 15 insertions, 1 deletions
@@ -296,7 +296,8 @@ all:: # Define USE_NED_ALLOCATOR if you want to replace the platforms default # memory allocators with the nedmalloc allocator written by Niall Douglas. # -# Define NO_REGEX if you have no or inferior regex support in your C library. +# Define NO_REGEX if your C library lacks regex support with REG_STARTEND +# feature. # # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the # user. diff --git a/git-compat-util.h b/git-compat-util.h index 1f8b5f3b1f..7047d281e5 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -942,6 +942,19 @@ void git_qsort(void *base, size_t nmemb, size_t size, #define qsort git_qsort #endif +#ifndef REG_STARTEND +#error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd" +#endif + +static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size, + size_t nmatch, regmatch_t pmatch[], int eflags) +{ + assert(nmatch > 0 && pmatch); + pmatch[0].rm_so = 0; + pmatch[0].rm_eo = size; + return regexec(preg, buf, nmatch, pmatch, eflags | REG_STARTEND); +} + #ifndef DIR_HAS_BSD_GROUP_SEMANTICS # define FORCE_DIR_SET_GID S_ISGID #else |