cvs: php4 /ext/standard string.c /ext/standard/tests/strings wordwrap.phpt
| From: | jim winstead | Date: | Fri, 04 Jan 2002 19:48:09 +0000 |
| Subject: | cvs: php4 /ext/standard string.c /ext/standard/tests/strings wordwrap.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-8943@lists.php.net to get a copy of this message | ||
jimw Fri Jan 4 14:48:09 2002 EDT
Added files:
/php4/ext/standard/tests/strings wordwrap.phpt
Modified files:
/php4/ext/standard string.c
Log:
Fixed segfault in wordwrap() when wrapping to zero width and using
multi-character break or trying to force cut (bug #12768, now fails
and issues a warning because forcing a zero-width cut doesn't make
sense). Also converted to new paramater-passing API and avoid making
an extra copy of the return values.
# also added tests.
@- Fixed segfault in wordwrap() when wrapping to zero width and using
@ multi-character break or trying to force cut (bug #12768). (Jim)
Index: php4/ext/standard/string.c
diff -u php4/ext/standard/string.c:1.258 php4/ext/standard/string.c:1.259
--- php4/ext/standard/string.c:1.258 Thu Jan 3 15:20:35 2002
+++ php4/ext/standard/string.c Fri Jan 4 14:48:07 2002
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: string.c,v 1.258 2002/01/03 20:20:35 hholzgra Exp $ */
+/* $Id: string.c,v 1.259 2002/01/04 19:48:07 jimw Exp $ */
/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
@@ -613,49 +613,27 @@
Wraps buffer to selected number of characters using string break char */
PHP_FUNCTION(wordwrap)
{
- zval **ptext, **plinelength, **pbreakchar, **cut;
- long i = 0, l = 0, pgr = 0, linelength = 0, last = 0, breakcharlen, docut = 0;
- char *text, *breakchar, *newtext;
- int argc = ZEND_NUM_ARGS();
+ char *text, *breakchar = "\n", *newtext;
+ int textlen, breakcharlen = 1, newtextlen;
+ long linelength = 75, i = 0, l = 0, pgr = 0, last = 0;
+ zend_bool docut = 0;
- if (argc < 1 || argc > 4 ||
- zend_get_parameters_ex(ZEND_NUM_ARGS(), &ptext, &plinelength, &pbreakchar, &cut)
== FAILURE) {
- WRONG_PARAM_COUNT;
- }
- convert_to_string_ex(ptext);
-
- if (Z_STRVAL_PP(ptext) == 0)
- RETURN_FALSE;
-
- text = Z_STRVAL_PP(ptext);
-
- if (argc > 1) {
- convert_to_long_ex(plinelength);
- linelength = Z_LVAL_PP(plinelength);
- }
- else {
- linelength = 75;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lsb", &text, &textlen,
&linelength, &breakchar, &breakcharlen, &docut) == FAILURE) {
+ return;
}
- if (argc > 2) {
- convert_to_string_ex(pbreakchar);
- breakchar = Z_STRVAL_PP(pbreakchar);
- breakcharlen = Z_STRLEN_PP(pbreakchar);
- }
- else {
- breakchar = "\n";
- breakcharlen = 1;
- }
+ if (textlen == 0)
+ RETURN_FALSE;
- if (argc > 3) {
- convert_to_long_ex(cut);
- docut = Z_LVAL_PP(cut);
+ if (linelength == 0 && docut) {
+ php_error(E_WARNING, "%s() can't force cut when width is
zero",get_active_function_name(TSRMLS_C));
+ RETURN_FALSE;
}
/* Special case for a single-character break as it needs no
additional storage space */
- if (breakcharlen == 1 && docut == 0) {
- newtext = estrndup(text, Z_STRLEN_PP(ptext));
+ if (breakcharlen == 1 && !docut) {
+ newtext = estrndup(text, textlen);
while (newtext[i] != '\0') {
/* prescan line to see if it is greater than linelength */
@@ -697,12 +675,12 @@
i += l + 1;
}
- RETVAL_STRINGL(newtext, strlen(newtext), 1);
- efree(newtext);
+ RETURN_STRINGL(newtext, textlen, 0);
}
else {
/* Multiple character line break */
- newtext = emalloc(Z_STRLEN_PP(ptext) * (breakcharlen + 1) + 1);
+ newtextlen = textlen * (breakcharlen + 1) + 1;
+ newtext = emalloc(newtextlen);
newtext[0] = '\0';
i = 0;
@@ -726,7 +704,7 @@
while (l >= 0) {
if (text[i+l] == ' ') {
strncat(newtext, text+last, i+l-last);
- strcat(newtext, breakchar);
+ strncat(newtext, breakchar, breakcharlen);
last = i + l + 1;
break;
}
@@ -737,19 +715,22 @@
/* couldn't break it backwards, try looking forwards */
l = linelength - 1;
while (l <= pgr) {
- if (docut == 0) {
+ if (!docut) {
if (text[i+l] == ' ') {
strncat(newtext, text+last, i+l-last);
- strcat(newtext, breakchar);
+ strncat(newtext, breakchar, breakcharlen);
last = i + l + 1;
+ ++l;
break;
}
}
- if (docut == 1) {
+ /* cut if longer than allowed */
+ else {
if (text[i+l] == ' ' || l > i-last) {
strncat(newtext, text+last, i+l-last+1);
- strcat(newtext, breakchar);
+ strncat(newtext, breakchar, breakcharlen);
last = i + l + 1;
+ ++l;
break;
}
}
@@ -764,11 +745,10 @@
}
if (i + l > last) {
- strcat(newtext, text+last);
+ strncat(newtext, text+last, i+l-last);
}
- RETVAL_STRINGL(newtext, strlen(newtext), 1);
- efree(newtext);
+ RETURN_STRINGL(newtext, strlen(newtext), 0);
}
}
/* }}} */
Index: php4/ext/standard/tests/strings/wordwrap.phpt
+++ php4/ext/standard/tests/strings/wordwrap.phpt
--TEST--
wordwrap() function
--POST--
--GET--
--FILE--
<?php
$tests = <<<TESTS
"12345 12345 12345 12345" === wordwrap("12345 12345 12345 12345")
"12345 12345\\n1234567890\\n1234567890" === wordwrap("12345 12345 1234567890
1234567890",12)
"12345\\n12345\\n12345\\n12345" === wordwrap("12345 12345 12345 12345",0)
"12345ab12345ab12345ab12345" === wordwrap("12345 12345 12345
12345",0,"ab")
"12345 12345ab1234567890ab1234567890" === wordwrap("12345 12345 1234567890
1234567890",12,"ab")
TESTS;
include('../../../../tests/quicktester.inc');
--EXPECT--
OK