php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #17547 Endless loop with file() when using compress.bzip2 wrapper
Submitted: 2002-05-31 17:36 UTC Modified: 2002-08-26 19:31 UTC
From: mfischer@php.net Assigned:
Status: Closed Package: Filesystem function related
PHP Version: 4.0CVS-2002-05-31 OS: Linux (maybe Windows too)
Private report: No CVE-ID: None
 [2002-05-31 17:36 UTC] mfischer@php.net
Using a simple bzip2 compressed input file like

$ cat test.txt
1 ene
2 mene
3 muh
4 foo

and compressing it with bzip2

$ bzip2 -c test.txt >test.bz2

and then trying to use file() with compress.bzip2 wrapper results in an infinite loop, i.e. never returned out of file():

$ cat test.php
<?
        print_r(file('compress.bzip2://test.bz2'));
?>

Looking at the code in file() using whil(1) { ... } seems dangerous for race conditions. But it actually works with e.g. compress.zlib wrapper and with normal files so I suspect this being a bug in the bz2 wrapper.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-05-31 20:50 UTC] mfischer@php.net
Actually it turned out to be a problem in main/streams.c . The fgets emulation code isn't right. I basicall ripped the one from gzgets() from zlib and it works:

Index: streams.c
===================================================================
RCS file: /repository/php4/main/streams.c,v
retrieving revision 1.52
diff -u -r1.52 streams.c
--- streams.c   30 Apr 2002 00:22:44 -0000      1.52
+++ streams.c   1 Jun 2002 00:46:43 -0000
@@ -248,21 +248,13 @@
                return NULL;
        } else {
                /* unbuffered fgets - poor performance ! */
-               size_t n = 1;
                char *c = buf;

                /* TODO: look at error returns? */

-               while(n < maxlen && stream->ops->read(stream, c, 1 TSRMLS_CC) > 0) {
-                       n++;
-                       if (*c == '\n') {
-                               c++;
-                               break;
-                       }
-                       c++;
-               }
-               *c = 0;
-               return buf;
+               while (--maxlen > 0 && stream->ops->read(stream, buf, 1 TSRMLS_CC) == 1 && *buf++ != '\n');
+               *buf = '\0';
+               return c == buf && maxlen > 0 ? NULL : c;
        }
 }

Does this sound reasonable, Wez?
 [2002-06-01 09:32 UTC] sniper@php.net
Wez is on vacation, just commit it. :)

 [2002-08-26 19:31 UTC] mfischer@php.net
Has been fixed some time ago.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 00:01:30 2024 UTC