1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
From deb06bbb9cbb31292fc219501614a8c3ff25bb11 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sat, 29 Dec 2018 19:51:24 -0800
Subject: [PATCH] Fix bug #77370 - check that we do not read past buffer end
when parsing multibytes
---
ext/mbstring/oniguruma/regparse.c | 9 +++++++++
ext/mbstring/tests/bug77370.phpt | 13 +++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 ext/mbstring/tests/bug77370.phpt
diff --git a/ext/mbstring/oniguruma/regparse.c b/ext/mbstring/oniguruma/regparse.c
index d2925f1e81b0..252ca1871202 100644
--- a/ext/mbstring/oniguruma/regparse.c
+++ b/ext/mbstring/oniguruma/regparse.c
@@ -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
index 000000000000..c4d25582fe3b
--- /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) ""
+}
|