From 67ea97dfdf18f07906b27af38f2348a628cf3e49 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sat, 18 Jun 2005 18:23:12 +0000 Subject: [PATCH] Added offset & length parameters to substr_count() function. --- NEWS | 1 + ext/standard/string.c | 24 +++++++++++++++++--- ext/standard/tests/strings/substr_count.phpt | 5 ++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index cb2aed10203..e6160d6c133 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PHP NEWS (Derick) - Added bindto socket context option. (Ilia) - Added offset parameter to the stream_copy_to_stream() function. (Ilia) +- Added offset & length parameters to substr_count() function. (Ilia) - Fixed PDO shutdown problem (possible inifite loop running rollback on shutdown). (Wez) - Fixed PECL bug #3714 (beginTransaction doesn't work if you're in diff --git a/ext/standard/string.c b/ext/standard/string.c index 9849e5ee8bb..6b8b633c9b3 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4420,15 +4420,16 @@ PHP_FUNCTION(strnatcasecmp) } /* }}} */ -/* {{{ proto int substr_count(string haystack, string needle) +/* {{{ proto int substr_count(string haystack, string needle [, int offset [, int length]]) Returns the number of times a substring occurs in the string */ PHP_FUNCTION(substr_count) { - zval **haystack, **needle; + zval **haystack, **needle, **offset, **length; + int ac = ZEND_NUM_ARGS(); int count = 0; char *p, *endp, cmp; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { + if (ac < 2 || ac > 4 || zend_get_parameters_ex(ac, &haystack, &needle, &offset, &length) == FAILURE) { WRONG_PARAM_COUNT; } @@ -4443,6 +4444,23 @@ PHP_FUNCTION(substr_count) p = Z_STRVAL_PP(haystack); endp = p + Z_STRLEN_PP(haystack); + if (ac > 2) { + convert_to_long_ex(offset); + p += Z_LVAL_PP(offset); + if (p > endp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset value %ld exceeds string length.", Z_LVAL_PP(offset)); + RETURN_FALSE; + } + if (ac == 4) { + convert_to_long_ex(length); + if ((p + Z_LVAL_PP(length)) > endp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length value %ld exceeds string length.", Z_LVAL_PP(length)); + RETURN_FALSE; + } + endp = p + Z_LVAL_PP(length); + } + } + if (Z_STRLEN_PP(needle) == 1) { cmp = Z_STRVAL_PP(needle)[0]; diff --git a/ext/standard/tests/strings/substr_count.phpt b/ext/standard/tests/strings/substr_count.phpt index 636590bb73a..6aee365340e 100644 --- a/ext/standard/tests/strings/substr_count.phpt +++ b/ext/standard/tests/strings/substr_count.phpt @@ -13,6 +13,9 @@ substr_count() function $a = str_repeat("abcacbabca", 100); var_dump(@substr_count($a, "bca")); + + var_dump(substr_count($a, "bca", 200)); + var_dump(substr_count($a, "bca", 200, 50)); ?> --EXPECT-- bool(false) @@ -22,3 +25,5 @@ int(0) int(0) int(100) int(200) +int(160) +int(10)