]> granicus.if.org Git - php/commitdiff
- Fixed bug #54092 (Segmentation fault when using HTTP proxy with the FTP
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 27 Feb 2011 20:23:54 +0000 (20:23 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 27 Feb 2011 20:23:54 +0000 (20:23 +0000)
  wrapper).
#php_stream->wrapperdata should hold an array zval (like its zval* type
#indicates...), it's not a place where the wrapper can drop an arbitrary
#pointer. For that, .wrapperthis should be used.
#Also, since the ftp dir wrapper defines its own stream type, it's more
#appropriate to use .abstract to store the stream instance specific data.

ext/standard/ftp_fopen_wrapper.c

index 653d2c61b08727f9fb7c98b311096c2add7a340d..accbbb8050f38ba27455597be97d010e23094b4e 100644 (file)
 #define FTPS_ENCRYPT_DATA 1
 #define GET_FTP_RESULT(stream) get_ftp_result((stream), tmp_line, sizeof(tmp_line) TSRMLS_CC)
 
+typedef struct _php_ftp_dirstream_data {
+       php_stream *datastream;
+       php_stream *controlstream;
+       php_stream *dirstream;
+} php_ftp_dirstream_data;
+
 /* {{{ get_ftp_result
  */
 static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer_size TSRMLS_DC)
@@ -97,7 +103,7 @@ static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper, php_stream *s
  */
 static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC)
 {
-       php_stream *controlstream = (php_stream *)stream->wrapperdata;
+       php_stream *controlstream = stream->wrapperthis;
        int ret = 0;
        
        if (controlstream) {
@@ -106,10 +112,6 @@ static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream *
                        int result;
 
                        /* For write modes close data stream first to signal EOF to server */
-                       stream->wrapperdata = NULL;
-                       php_stream_close(stream);
-                       stream = NULL;
-
                        result = GET_FTP_RESULT(controlstream);
                        if (result != 226 && result != 250) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "FTP server error %d:%s", result, tmp_line);
@@ -119,9 +121,7 @@ static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream *
 
                php_stream_write_string(controlstream, "QUIT\r\n");
                php_stream_close(controlstream);
-               if (stream) {
-                       stream->wrapperdata = NULL;
-               }
+               stream->wrapperthis = NULL;
        }
 
        return ret;
@@ -583,7 +583,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
        }
 
        /* remember control stream */   
-       datastream->wrapperdata = (zval *)stream;
+       datastream->wrapperthis = stream;
 
        php_url_free(resource);
        return datastream;
@@ -607,11 +607,13 @@ errexit:
 static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
 {
        php_stream_dirent *ent = (php_stream_dirent *)buf;
-       php_stream *innerstream = (php_stream *)stream->abstract;
+       php_stream *innerstream;
        size_t tmp_len;
        char *basename;
        size_t basename_len;
 
+       innerstream =  ((php_ftp_dirstream_data *)stream->abstract)->datastream;
+
        if (count != sizeof(php_stream_dirent)) {
                return 0;
        }
@@ -655,13 +657,18 @@ static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count
  */
 static int php_ftp_dirstream_close(php_stream *stream, int close_handle TSRMLS_DC)
 {
-       php_stream *innerstream = (php_stream *)stream->abstract;
+       php_ftp_dirstream_data *data = stream->abstract;
 
-       if (innerstream->wrapperdata) {
-               php_stream_close((php_stream *)innerstream->wrapperdata);
-               innerstream->wrapperdata = NULL;
+       /* close control connection */
+       if (data->controlstream) {
+               php_stream_close(data->controlstream);
+               data->controlstream = NULL;
        }
-       php_stream_close((php_stream *)stream->abstract);
+       /* close data connection */
+       php_stream_close(data->datastream);
+       data->datastream = NULL;
+       
+       efree(data);
        stream->abstract = NULL;
 
        return 0;
@@ -687,6 +694,7 @@ static php_stream_ops php_ftp_dirstream_ops = {
 php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
 {
        php_stream *stream, *reuseid, *datastream = NULL;
+       php_ftp_dirstream_data *dirsdata;
        php_url *resource = NULL;
        int result = 0, use_ssl, use_ssl_on_data = 0;
        char *hoststart = NULL, tmp_line[512];
@@ -746,11 +754,14 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, cha
                goto opendir_errexit;
        }
 
-       /* remember control stream */   
-       datastream->wrapperdata = (zval *)stream;
-
        php_url_free(resource);
-       return php_stream_alloc(&php_ftp_dirstream_ops, datastream, 0, mode);
+
+       dirsdata = emalloc(sizeof *dirsdata);
+       dirsdata->datastream = datastream;
+       dirsdata->controlstream = stream;
+       dirsdata->dirstream = php_stream_alloc(&php_ftp_dirstream_ops, dirsdata, 0, mode);
+
+       return dirsdata->dirstream;
 
 opendir_errexit:
        if (resource) {