]> granicus.if.org Git - php/commitdiff
Fix more issues with encodilng length
authorStanislav Malyshev <stas@php.net>
Wed, 2 Jan 2019 08:36:30 +0000 (00:36 -0800)
committerStanislav Malyshev <stas@php.net>
Sun, 6 Jan 2019 19:38:46 +0000 (11:38 -0800)
Should fix bug #77381, bug #77382, bug #77385, bug #77394.

ext/mbstring/oniguruma/enc/unicode.c
ext/mbstring/oniguruma/regcomp.c
ext/mbstring/oniguruma/regparse.c
ext/mbstring/oniguruma/regparse.h
ext/mbstring/tests/bug77371.phpt
ext/mbstring/tests/bug77381.phpt [new file with mode: 0644]

index e13429f51e9c4f2075dbed0bdd25d5febaab6c31..9f86095896b6c5bb1980ab1fbfc042e94b0d3dd7 100644 (file)
@@ -10989,6 +10989,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
index c72d65d6942f8920faa4fc418d9228fff11d0da4..820257341f54cffad1f1df8ffb511061f5541933 100644 (file)
@@ -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,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++;
     }
@@ -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)) {
index 252ca187120238a77055ca51b40f7e5f14250d9c..fcfaf4378c0613a95bcc5b0ee97344331c1cee07 100644 (file)
@@ -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
 
@@ -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;
     }
index 0c5c2c936c0449438ee722a57f6d5e9d6f9b7e5e..bcab03ed589210ff6f3070e8505bad1991c399a9 100644 (file)
@@ -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 */
index f23445bd0917de5827dcbc839d3de918a3e5ec90..33e5fc115c966f5fff67789b2c6b34a64ed024d1 100644 (file)
@@ -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)
\ No newline at end of file
diff --git a/ext/mbstring/tests/bug77381.phpt b/ext/mbstring/tests/bug77381.phpt
new file mode 100644 (file)
index 0000000..cb83759
--- /dev/null
@@ -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)