Fix #66797: mb_substr only takes 32-bit signed integer

`from` and `len` are `long`, but get passed to mbfl_substr() which expects
`int`s. Therefore we clamp the values to avoid the undefined conversion
behavior.
This commit is contained in:
Christoph M. Becker 2016-08-30 14:48:24 +02:00
parent af7828a20f
commit 2f10db36af
3 changed files with 33 additions and 0 deletions

3
NEWS
View file

@ -31,6 +31,9 @@ PHP NEWS
- JSON: - JSON:
. Fixed bug #72787 (json_decode reads out of bounds). (Jakub Zelenka) . Fixed bug #72787 (json_decode reads out of bounds). (Jakub Zelenka)
- mbstring:
. Fixed bug #66797 (mb_substr only takes 32-bit signed integer). (cmb)
- MSSQL: - MSSQL:
. Fixed bug #72039 (Use of uninitialised value on mssql_guid_string). (Kalle) . Fixed bug #72039 (Use of uninitialised value on mssql_guid_string). (Kalle)

View file

@ -2799,6 +2799,13 @@ PHP_FUNCTION(mb_substr)
RETURN_FALSE; RETURN_FALSE;
} }
if (from > INT_MAX) {
from = INT_MAX;
}
if (len > INT_MAX) {
len = INT_MAX;
}
ret = mbfl_substr(&string, &result, from, len); ret = mbfl_substr(&string, &result, from, len);
if (NULL == ret) { if (NULL == ret) {
RETURN_FALSE; RETURN_FALSE;

View file

@ -0,0 +1,23 @@
--TEST--
Bug #66797 (mb_substr only takes 32-bit signed integer)
--SKIPIF--
<?php
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
?>
--FILE--
<?php
var_dump(
mb_substr('bar', 0, 0x7fffffff),
mb_substr('bar', 0, 0x80000000),
mb_substr('bar', 0xffffffff, 1),
mb_substr('bar', 0x100000000, 1)
);
?>
==DONE==
--EXPECTF--
string(3) "bar"
string(3) "bar"
string(0) ""
string(0) ""
==DONE==