Stanislav Malyshev wrote:

> Recently, PHP started to segfault for me on URL fopen, e.g.:
> fopen("http://www.host.com","r";) brings immediate segfault.
> 
> Investigation showed that the problem happens in php_sock_fgets_internal
> (file fsock.c), in the first SEARCHCR() statement and is because when sock
> parameter is passed to php_sock_fgets_internal, both readbuf and readpos
> are 0, and SEARCHCR does p = READPTR(sock), which makes p be 0 too, and
> then uses *p != '\n' as a condition.
> Could anybody who know the code look at this and check what has gone
> wrong?
> 

Here's what I came up with:

What it was (latest CVS I have, fsock.c revision 1.74): 

#define SEARCHCR() do { \
        for (p = READPTR(sock), pe = p + MIN(TOREAD(sock), maxlen); \

                        *p != '\n'; ) if (++p >= pe) { p = NULL; break; }   
    \

} while (0)


What I did instead:

#define SEARCHCR() \
    if (MIN(TOREAD(sock), maxlen) == 0) \
        p = NULL; \
    else { \

        for (p = READPTR(sock), pe = p + MIN(TOREAD(sock), maxlen); *p != 
'\n'; p++) { \

            if (p >= pe) { \
                p = NULL; \
                break; \
            } \
        } \
    }


That seems to work nicely. Looks like crap, but it works. It also fires 
off some warnings about comparing READPTR(sock) to 0 since you're 
comparing a pointer address to an integer, but that shouldn't be a big deal.

A patch  follows if anybody's interested.

btw, this is my first ever patch submitted for PHP, so if it totally sucks, 
be kind.

J



Patch:

--- ext/standard/fsock.c        Tue Jul 31 17:27:42 2001
+++ ext/standard/newfsock.c        Tue Jul 31 17:34:31 2001
@@ -89,10 +89,18 @@
                efree(key);                                \
        }

-#define SEARCHCR() do { \
-        for (p = READPTR(sock), pe = p + MIN(TOREAD(sock), maxlen); \
-                *p != '\n'; ) if (++p >= pe) { p = NULL; break; } \
-} while (0)
+#define SEARCHCR() \
+        if (MIN(TOREAD(sock), maxlen) == 0) \
+                p = NULL; \
+        else { \
+                for (p = READPTR(sock), pe = p + MIN(TOREAD(sock),maxlen); 
*p != '\n'; p++) { \
+                        if (p >= pe) { \
+                                p = NULL; \
+                                break; \
+                        } \
+                } \
+        }
+        

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to