summaryrefslogtreecommitdiffstats
path: root/bug73240.patch
blob: 9f0d43511b9b2ce1013c0d6ad122e57a3fc5dccd (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
Backported from 5.6.27 by Remi.


From 8259130b6bc752968856b352c9e7f8e03a8c0a8e Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Mon, 10 Oct 2016 23:42:50 -0700
Subject: [PATCH] Fix for #73240 - Write out of bounds at number_format

---
 ext/standard/math.c | 108 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 60 insertions(+), 48 deletions(-)

diff --git a/ext/standard/math.c b/ext/standard/math.c
index 5ffeff7..8290b20 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -1099,13 +1099,13 @@ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char tho
 
 static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
 		size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len,
-		int *result_len)
+		size_t *result_len)
 {
 	char *tmpbuf = NULL, *resbuf;
 	char *s, *t;  /* source, target */
 	char *dp;
-	int integral;
-	int tmplen, reslen=0;
+	size_t integral;
+	size_t tmplen, reslen=0;
 	int count=0;
 	int is_negative=0;
 
@@ -1144,15 +1144,23 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
 
 	/* allow for thousand separators */
 	if (thousand_sep) {
+		if (integral + thousand_sep_len * ((integral-1) / 3) < integral) {
+			/* overflow */
+			php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+		}
 		integral += thousand_sep_len * ((integral-1) / 3);
 	}
-	
+
 	reslen = integral;
-	
+
 	if (dec) {
 		reslen += dec;
 
 		if (dec_point) {
+			if (reslen + dec_point < dec_point) {
+				/* overflow */
+				php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+			}
 			reslen += dec_point_len;
 		}
 	}
@@ -1235,17 +1243,21 @@ PHP_FUNCTION(number_format)
 	char *thousand_sep = NULL, *dec_point = NULL;
 	char thousand_sep_chr = ',', dec_point_chr = '.';
 	int thousand_sep_len = 0, dec_point_len = 0;
-	
+	char *formatted;
+	size_t formatted_len;
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) {
 		return;
 	}
 
 	switch(ZEND_NUM_ARGS()) {
 	case 1:
-		RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0);
+		formatted = _php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr);
+		formatted_len = strlen(formatted);
 		break;
 	case 2:
-		RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0);
+		formatted = _php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr);
+		formatted_len = strlen(formatted);
 		break;
 	case 4:
 		if (dec_point == NULL) {
@@ -1258,15 +1270,15 @@ PHP_FUNCTION(number_format)
 			thousand_sep_len = 1;
 		}
 
-		Z_TYPE_P(return_value) = IS_STRING;
-		Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec,
+		formatted = _php_math_number_format_ex_len(num, dec,
 				dec_point, dec_point_len, thousand_sep, thousand_sep_len,
-				&Z_STRLEN_P(return_value));
+				&formatted_len);
 		break;
 	default:
 		WRONG_PARAM_COUNT;
-		break;
+		return;
 	}
+	RETVAL_STRINGL_CHECK(formatted, formatted_len, 0);
 }
 /* }}} */
 
-- 
2.1.4

From c1112ff323c9dd1a4596aa4272e918acf0f797eb Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Tue, 11 Oct 2016 14:39:16 -0700
Subject: [PATCH] fix tsrm

---
 ext/standard/math.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ext/standard/math.c b/ext/standard/math.c
index 8290b20..bb64425 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -1146,7 +1146,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
 	if (thousand_sep) {
 		if (integral + thousand_sep_len * ((integral-1) / 3) < integral) {
 			/* overflow */
-			php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+			zend_error(E_ERROR, "String overflow");
 		}
 		integral += thousand_sep_len * ((integral-1) / 3);
 	}
@@ -1159,7 +1159,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
 		if (dec_point) {
 			if (reslen + dec_point < dec_point) {
 				/* overflow */
-				php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+				zend_error(E_ERROR, "String overflow");
 			}
 			reslen += dec_point_len;
 		}
-- 
2.1.4