php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #26938 exec does not read consecutive long lines correctly
Submitted: 2004-01-16 16:38 UTC Modified: 2004-01-21 11:51 UTC
From: runekl at opoint dot com Assigned:
Status: Closed Package: Program Execution
PHP Version: 5CVS OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: runekl at opoint dot com
New email:
PHP Version: OS:

 

 [2004-01-16 16:38 UTC] runekl at opoint dot com
Description:
------------
Exec fails to read two consecutive lines longer than 2*EXEC_INPUT_BUF correctly.  While reading the first line, buflen is set to 3*EXEC_INPUT_BUF.  When reading part two of the second line, bufl will be EXEC_INPUT_BUF to large since b!=buf.

Here is a patch:

Index: exec.c
===================================================================
RCS file: /repository/php-src/ext/standard/exec.c,v
retrieving revision 1.108
diff -C4 -r1.108 exec.c
*** exec.c      8 Jan 2004 08:17:31 -0000       1.108
--- exec.c      16 Jan 2004 21:35:35 -0000
***************
*** 111,132 ****

        if (type != 3) {
                b = buf;

!               while (php_stream_get_line(stream, b, EXEC_INPUT_BUF, &bufl)) {
                        /* no new line found, let's read some more */
                        if (b[bufl - 1] != '\n' && !php_stream_eof(stream)) {
                                if (buflen < (bufl + (b - buf) + EXEC_INPUT_BUF)) {
                                        bufl += b - buf;
!                                       buflen = bufl + EXEC_INPUT_BUF;
                                        buf = erealloc(buf, buflen);
                                        b = buf + bufl;
                                } else {
                                        b += bufl;
                                }
                                continue;
                        } else if (b != buf) {
!                               bufl += buflen - EXEC_INPUT_BUF;
                        }

                        if (type == 1) {
                                PHPWRITE(buf, bufl);
--- 111,132 ----

        if (type != 3) {
                b = buf;

!               while (php_stream_get_line(stream, b, buflen - (b - buf), &bufl)) {
                        /* no new line found, let's read some more */
                        if (b[bufl - 1] != '\n' && !php_stream_eof(stream)) {
                                if (buflen < (bufl + (b - buf) + EXEC_INPUT_BUF)) {
                                        bufl += b - buf;
!                                       buflen = bufl + 1 + EXEC_INPUT_BUF;
                                        buf = erealloc(buf, buflen);
                                        b = buf + bufl;
                                } else {
                                        b += bufl;
                                }
                                continue;
                        } else if (b != buf) {
!                               bufl += (b - buf);
                        }

                        if (type == 1) {
                                PHPWRITE(buf, bufl);



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-01-17 10:20 UTC] runekl at opoint dot com
I suggest you replace the test for bug 26615 with the one below.  That should cover both cases.  It will also make your distribution smaller -)

--TEST--
Bug #26615 (exec crash on long input lines)
--FILE--
<?php
$out = array();
$status = -1;
$php = getenv('TEST_PHP_EXECUTABLE');
exec($php . ' -r \'' 
     . '$lengths = array(10,20000,10000,5,10000,3);'
     . 'foreach($lengths as $length) {'
     . '  for($i=0;$i<$length;$i++) print chr(65+$i % 27);'
     . '  print "\n";'
     . '}\'', $out, $status);
for ($i=0;$i<6;$i++)
     print "md5(line $i)= " . md5($out[$i]) . " (length " . strlen($out[$i]) . ")\n";
?>
--EXPECT--
md5(line 0)= e86410fa2d6e2634fd8ac5f4b3afe7f3 (length 10)
md5(line 1)= e84debf3a1d132871d7fe45c1c04c566 (length 20000)
md5(line 2)= c33b4d2f86908eea5d75ee5a61fd81f4 (length 10000)
md5(line 3)= 2ecdde3959051d913f61b14579ea136d (length 5)
md5(line 4)= c33b4d2f86908eea5d75ee5a61fd81f4 (length 10000)
md5(line 5)= 902fbdd2b1df0c4f70b4a5d23525e932 (length 3)
 [2004-01-18 16:11 UTC] runekl at opoint dot com
I get the this when running the test I have suggested.

md5(line 0)= e86410fa2d6e2634fd8ac5f4b3afe7f3 (length 10)
md5(line 1)= e84debf3a1d132871d7fe45c1c04c566 (length 20000)
md5(line 2)= 2713d01e967adfd64c49857370ab420b (length 18191)
md5(line 3)= 2ecdde3959051d913f61b14579ea136d (length 5)
md5(line 4)= 2713d01e967adfd64c49857370ab420b (length 18191)
md5(line 5)= 902fbdd2b1df0c4f70b4a5d23525e932 (length 3)

Look at the lines 2 and 4.  The lines to read are 10000 characters long, but PHP 'reads' 18191 bytes, e.g. 2*EXEC_INPUT_BUF-1 to much.  The extra characters come from line 1.

With the patch in my first post I get correct output.

Since test 26615 does not test reading long lines good enough and is about a bug in the same loop, I suggest replacing it.
 [2004-01-19 19:44 UTC] sniper@php.net
I can reproduce this now, got the same result.
Can you provide that patch in unified diff format? (diff -u)

 [2004-01-20 01:05 UTC] runekl at opoint dot com
Here it is:

Index: exec.c
===================================================================
RCS file: /repository/php-src/ext/standard/exec.c,v
retrieving revision 1.108
diff -u -r1.108 exec.c
--- exec.c      8 Jan 2004 08:17:31 -0000       1.108
+++ exec.c      20 Jan 2004 06:07:37 -0000
@@ -112,12 +112,12 @@
        if (type != 3) {
                b = buf;

-               while (php_stream_get_line(stream, b, EXEC_INPUT_BUF, &bufl)) {
+               while (php_stream_get_line(stream, b, buflen - (b - buf), &bufl)) {
                        /* no new line found, let's read some more */
                        if (b[bufl - 1] != '\n' && !php_stream_eof(stream)) {
                                if (buflen < (bufl + (b - buf) + EXEC_INPUT_BUF)) {
                                        bufl += b - buf;
-                                       buflen = bufl + EXEC_INPUT_BUF;
+                                       buflen = bufl + 1 + EXEC_INPUT_BUF;
                                        buf = erealloc(buf, buflen);
                                        b = buf + bufl;
                                } else {
@@ -125,7 +125,7 @@
                                }
                                continue;
                        } else if (b != buf) {
-                               bufl += buflen - EXEC_INPUT_BUF;
+                               bufl += (b - buf);
                        }

                        if (type == 1) {
 [2004-01-21 11:51 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC