diff options
Diffstat (limited to 'ext/mbstring')
-rw-r--r-- | ext/mbstring/oniguruma/src/regcomp.c | 10 | ||||
-rw-r--r-- | ext/mbstring/oniguruma/src/regparse.c | 6 | ||||
-rw-r--r-- | ext/mbstring/oniguruma/src/regparse.h | 12 | ||||
-rw-r--r-- | ext/mbstring/tests/bug77370.phpt | 13 | ||||
-rw-r--r-- | ext/mbstring/tests/bug77371.phpt | 10 | ||||
-rw-r--r-- | ext/mbstring/tests/bug77381.phpt | 16 |
6 files changed, 62 insertions, 5 deletions
diff --git a/ext/mbstring/oniguruma/src/regcomp.c b/ext/mbstring/oniguruma/src/regcomp.c index 0e9a9ab38c..3f4c95be6b 100644 --- a/ext/mbstring/oniguruma/src/regcomp.c +++ b/ext/mbstring/oniguruma/src/regcomp.c @@ -469,13 +469,13 @@ compile_length_string_node(Node* node, regex_t* reg) ambig = NSTRING_IS_AMBIG(node); p = prev = sn->s; - prev_len = enclen(enc, p); + SAFE_ENC_LEN(enc, p, sn->end, prev_len); p += prev_len; slen = 1; rlen = 0; for (; p < sn->end; ) { - len = enclen(enc, p); + SAFE_ENC_LEN(enc, p, sn->end, len); if (len == prev_len) { slen++; } @@ -518,12 +518,12 @@ compile_string_node(Node* node, regex_t* reg) ambig = NSTRING_IS_AMBIG(node); p = prev = sn->s; - prev_len = enclen(enc, p); + SAFE_ENC_LEN(enc, p, end, prev_len); p += prev_len; slen = 1; for (; p < end; ) { - len = enclen(enc, p); + SAFE_ENC_LEN(enc, p, end, len); if (len == prev_len) { slen++; } @@ -3435,7 +3435,7 @@ expand_case_fold_string(Node* node, regex_t* reg) goto err; } - len = enclen(reg->enc, p); + SAFE_ENC_LEN(reg->enc, p, end, len); if (n == 0) { if (IS_NULL(snode)) { diff --git a/ext/mbstring/oniguruma/src/regparse.c b/ext/mbstring/oniguruma/src/regparse.c index 8153513202..0c0b07804b 100644 --- a/ext/mbstring/oniguruma/src/regparse.c +++ b/ext/mbstring/oniguruma/src/regparse.c @@ -304,14 +304,17 @@ strdup_with_null(OnigEncoding enc, UChar* s, UChar* end) c = ONIGENC_MBC_TO_CODE(enc, p, end); \ pfetch_prev = p; \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PINC_S do { \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PFETCH_S(c) do { \ c = ONIGENC_MBC_TO_CODE(enc, p, end); \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PPEEK (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE) @@ -3594,6 +3597,9 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env) } else { /* string */ p = tok->backp + enclen(enc, tok->backp); + int len; + SAFE_ENC_LEN(enc, tok->backp, end, len); + p = tok->backp + len; } } break; diff --git a/ext/mbstring/oniguruma/src/regparse.h b/ext/mbstring/oniguruma/src/regparse.h index c9d1fe8a6e..6fc8152aa4 100644 --- a/ext/mbstring/oniguruma/src/regparse.h +++ b/ext/mbstring/oniguruma/src/regparse.h @@ -348,4 +348,16 @@ extern int onig_print_names(FILE*, regex_t*); #endif #endif +#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) +# define UNEXPECTED(condition) __builtin_expect(condition, 0) +#else +# define UNEXPECTED(condition) (condition) +#endif + +#define SAFE_ENC_LEN(enc, p, end, res) do { \ + int __res = enclen(enc, p); \ + if (UNEXPECTED(p + __res > end)) __res = end - p; \ + res = __res; \ +} while(0); + #endif /* REGPARSE_H */ diff --git a/ext/mbstring/tests/bug77370.phpt b/ext/mbstring/tests/bug77370.phpt new file mode 100644 index 0000000000..c4d25582fe --- /dev/null +++ b/ext/mbstring/tests/bug77370.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #77370 (Buffer overflow on mb regex functions - fetch_token) +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump(mb_split(" \xfd","")); +?> +--EXPECT-- +array(1) { + [0]=> + string(0) "" +} diff --git a/ext/mbstring/tests/bug77371.phpt b/ext/mbstring/tests/bug77371.phpt new file mode 100644 index 0000000000..33e5fc115c --- /dev/null +++ b/ext/mbstring/tests/bug77371.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #77371 (heap buffer overflow in mb regex functions - compile_string_node) +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc","")); +?> +--EXPECT-- +bool(false)
\ No newline at end of file diff --git a/ext/mbstring/tests/bug77381.phpt b/ext/mbstring/tests/bug77381.phpt new file mode 100644 index 0000000000..cb83759fc0 --- /dev/null +++ b/ext/mbstring/tests/bug77381.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #77381 (heap buffer overflow in multibyte match_at) +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump(mb_ereg("000||0\xfa","0")); +var_dump(mb_ereg("(?i)000000000000000000000\xf0","")); +var_dump(mb_ereg("0000\\"."\xf5","0")); +var_dump(mb_ereg("(?i)FFF00000000000000000\xfd","")); +?> +--EXPECT-- +int(1) +bool(false) +bool(false) +bool(false) |