Skip to content

Commit 91ceb29

Browse files
committed
Fixed substr(), but no kidding now.
all the signed/unsigned arithmetic needs clear understanding
1 parent 99442a3 commit 91ceb29

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

ext/standard/string.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,11 +2212,12 @@ PHP_FUNCTION(chunk_split)
22122212

22132213
/* {{{ proto string substr(string str, int start [, int length])
22142214
Returns part of a string */
2215+
/* XXX This function has to be revised when a better php integer type was integrated */
22152216
PHP_FUNCTION(substr)
22162217
{
22172218
char *str;
22182219
long l = 0, f;
2219-
zend_str_size str_len;
2220+
zend_str_size_int str_len;
22202221
int argc = ZEND_NUM_ARGS();
22212222

22222223
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sl|l", &str, &str_len, &f, &l) == FAILURE) {
@@ -2226,28 +2227,28 @@ PHP_FUNCTION(substr)
22262227
if (argc > 2) {
22272228
if ((l < 0 && -l > str_len)) {
22282229
RETURN_FALSE;
2229-
} else if (l >= 0 && l > str_len) {
2230+
} else if (l > (long)str_len) {
22302231
l = str_len;
22312232
}
22322233
} else {
22332234
l = str_len;
22342235
}
22352236

2236-
if (f > 0 && f > str_len) {
2237+
if (f > (long)str_len) {
22372238
RETURN_FALSE;
22382239
} else if (f < 0 && -f > str_len) {
22392240
f = 0;
22402241
}
22412242

2242-
if (l < 0 && ((f > 0 && (l + str_len) < f) || (f < 0 && (l+str_len) > -f))) {
2243+
if (l < 0 && (l + (long)str_len - f) < 0) {
22432244
RETURN_FALSE;
22442245
}
22452246

22462247
/* if "from" position is negative, count start position from the end
22472248
* of the string
22482249
*/
22492250
if (f < 0) {
2250-
f = str_len + f;
2251+
f = (long)str_len + f;
22512252
if (f < 0) {
22522253
f = 0;
22532254
}
@@ -2257,17 +2258,17 @@ PHP_FUNCTION(substr)
22572258
* needed to stop that many chars from the end of the string
22582259
*/
22592260
if (l < 0) {
2260-
l = (str_len - f) + l;
2261+
l = ((long)str_len - f) + l;
22612262
if (l < 0) {
22622263
l = 0;
22632264
}
22642265
}
22652266

2266-
if (f >= str_len) {
2267+
if (f >= (long)str_len) {
22672268
RETURN_FALSE;
22682269
}
22692270

2270-
if ((f + l) > str_len) {
2271+
if ((f + l) > (long)str_len) {
22712272
l = str_len - f;
22722273
}
22732274

0 commit comments

Comments
 (0)