summaryrefslogtreecommitdiffstats
path: root/bug72400.patch
blob: 363a59864e0c56779062c64c2e4a80b6cbde9dab (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
Backported from 5.5.37 for 5.4 by Remi Collet


From 88746d60ab3ad51797612ee62603bb3e08d4aac4 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Wed, 15 Jun 2016 21:46:46 -0700
Subject: [PATCH] Fix bug #72400 and #72403 - prevent signed int overflows for
 string lengths

---
 ext/standard/string.c | 25 ++++++++++++--
 ext/standard/url.c    | 96 +++++++++++++++++++++++++++------------------------
 2 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/ext/standard/string.c b/ext/standard/string.c
index 63eede1..acb6a01 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -137,6 +137,9 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
 	register unsigned char *result = NULL;
 	size_t i, j;
 
+	if (UNEXPECTED(oldlen * 2 * sizeof(char) > INT_MAX)) {
+		zend_error(E_ERROR, "String size overflow");
+	}
 	result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1);
 
 	for (i = j = 0; i < oldlen; i++) {
@@ -2602,6 +2605,7 @@ PHP_FUNCTION(quotemeta)
 	char *p, *q;
 	char c;
 	int  old_len;
+	size_t new_len;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) {
 		return;
@@ -2636,8 +2640,13 @@ PHP_FUNCTION(quotemeta)
 		}
 	}
 	*q = 0;
+	new_len = q - str;
+	if (UNEXPECTED(new_len > INT_MAX)) {
+		efree(str);
+		zend_error(E_ERROR, "String size overflow");
+	}
 
-	RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0);
+	RETURN_STRINGL(erealloc(str, new_len + 1), new_len, 0);
 }
 /* }}} */
 
@@ -3539,7 +3548,7 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s
 	char *source, *target;
 	char *end;
 	char c;
-	int  newlen;
+	size_t  newlen;
 
 	if (!wlength) {
 		wlength = strlen(what);
@@ -3570,11 +3579,15 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s
 	}
 	*target = 0;
 	newlen = target - new_str;
+	if (UNEXPECTED(newlen > INT_MAX)) {
+		efree(new_str);
+		zend_error(E_ERROR, "String size overflow");
+	}
 	if (target - new_str < length * 4) {
 		new_str = erealloc(new_str, newlen + 1);
 	}
 	if (new_length) {
-		*new_length = newlen;
+		*new_length = (int)newlen;
 	}
 	if (should_free) {
 		STR_FREE((char*)str);
@@ -3626,6 +3639,9 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f
 
 	*target = 0;
 	*new_length = target - new_str;
+	if (UNEXPECTED(*new_length < 0)) {
+		zend_error(E_ERROR, "String size overflow");
+	}
 	if (should_free) {
 		STR_FREE(str);
 	}
@@ -4329,6 +4345,9 @@ PHP_FUNCTION(nl2br)
 		size_t repl_len = is_xhtml ? (sizeof("<br />") - 1) : (sizeof("<br>") - 1);
 
 		new_length = str_len + repl_cnt * repl_len;
+		if (UNEXPECTED(new_length > INT_MAX)) {
+			zend_error(E_ERROR, "String size overflow");
+		}
 		tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1);
 	}
 
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 27a216a..fc3f080 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -626,6 +626,10 @@ PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
 	if (new_length) {
 		*new_length = y;
 	}
+	if (UNEXPECTED(y > INT_MAX)) {
+		efree(str);
+		zend_error(E_ERROR, "String size overflow");
+	}
 	return ((char *) str);
 }
 /* }}} */