]> granicus.if.org Git - php/commitdiff
Fix bug #77370 - check that we do not read past buffer end when parsing multibytes
authorStanislav Malyshev <stas@php.net>
Sun, 30 Dec 2018 03:51:24 +0000 (19:51 -0800)
committerStanislav Malyshev <stas@php.net>
Sun, 6 Jan 2019 19:33:44 +0000 (11:33 -0800)
ext/mbstring/oniguruma/regparse.c
ext/mbstring/tests/bug77370.phpt [new file with mode: 0644]

index d2925f1e81b0bb827db02b260cca1058355135d2..252ca187120238a77055ca51b40f7e5f14250d9c 100644 (file)
@@ -246,6 +246,12 @@ 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
 
@@ -260,14 +266,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)
diff --git a/ext/mbstring/tests/bug77370.phpt b/ext/mbstring/tests/bug77370.phpt
new file mode 100644 (file)
index 0000000..c4d2558
--- /dev/null
@@ -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) ""
+}