Re: cvs: php4 /ext/standard string.c /ext/standard/tests/strings wordwrap.phpt

From: Date: Sat, 05 Jan 2002 14:59:40 +0000
Subject: Re: cvs: php4 /ext/standard string.c /ext/standard/tests/strings wordwrap.phpt
References: 1  Groups: php.cvs 
Request: Send a blank email to php-cvs+get-8955@lists.php.net to get a copy of this message
If you need to use something like strncat()/strncpy() you should use strlcpy()/strlcat(). We changed to these functions a couple of years ago. Andi At 07:48 PM 1/4/2002 +0000, jim winstead wrote:
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 -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, e-mail: php-cvs-unsubscribe@lists.php.net For additional commands, e-mail: php-cvs-help@lists.php.net To contact the list administrators, e-mail: php-list-admin@lists.php.net


« previous php.cvs (#8955) next »