Skip to content

Commit

Permalink
Fix more issues with encodilng length
Browse files Browse the repository at this point in the history
Should fix bug #77381, bug #77382, bug #77385, bug #77394.
  • Loading branch information
smalyshev committed Jan 6, 2019
1 parent 7a12dad commit c95daa9
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 14 deletions.
1 change: 1 addition & 0 deletions ext/mbstring/oniguruma/enc/unicode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10971,6 +10971,7 @@ onigenc_unicode_mbc_case_fold(OnigEncoding enc,

code = ONIGENC_MBC_TO_CODE(enc, p, end);
len = enclen(enc, p);
if (*pp + len > end) len = end - *pp;
*pp += len;

#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
Expand Down
11 changes: 5 additions & 6 deletions ext/mbstring/oniguruma/regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
Expand Down Expand Up @@ -518,13 +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);
if (p + len > end) len = end - p;
SAFE_ENC_LEN(enc, p, end, len);
if (len == prev_len) {
slen++;
}
Expand Down Expand Up @@ -3391,7 +3390,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)) {
Expand Down
10 changes: 3 additions & 7 deletions ext/mbstring/oniguruma/regparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,6 @@ strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
}
#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

/* scan pattern methods */
#define PEND_VALUE 0

Expand Down Expand Up @@ -3589,7 +3583,9 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
tok->u.code = (OnigCodePoint )num;
}
else { /* string */
p = tok->backp + enclen(enc, tok->backp);
int len;
SAFE_ENC_LEN(enc, tok->backp, end, len);
p = tok->backp + len;
}
break;
}
Expand Down
12 changes: 12 additions & 0 deletions ext/mbstring/oniguruma/regparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion ext/mbstring/tests/bug77371.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Bug #77371 (heap buffer overflow in mb regex functions - compile_string_node)
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
--FILE--
<?php
var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc",""))
var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc",""));
?>
--EXPECT--
bool(false)
16 changes: 16 additions & 0 deletions ext/mbstring/tests/bug77381.phpt
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit c95daa9

Please sign in to comment.