cataphract Sun, 27 Feb 2011 20:23:54 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=308734
Log: - Fixed bug #54092 (Segmentation fault when using HTTP proxy with the FTP 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. Bug: http://bugs.php.net/54092 (Assigned) Segmentation fault when using FTP proxy Changed paths: U php/php-src/branches/PHP_5_3/NEWS U php/php-src/branches/PHP_5_3/ext/standard/ftp_fopen_wrapper.c U php/php-src/trunk/ext/standard/ftp_fopen_wrapper.c
Modified: php/php-src/branches/PHP_5_3/NEWS =================================================================== --- php/php-src/branches/PHP_5_3/NEWS 2011-02-27 20:10:08 UTC (rev 308733) +++ php/php-src/branches/PHP_5_3/NEWS 2011-02-27 20:23:54 UTC (rev 308734) @@ -191,6 +191,8 @@ all of the rows have been fetched). (Scott) - Streams: + . Fixed bug #54092 (Segmentation fault when using HTTP proxy with the FTP + wrapper). (Gustavo) . Fixed bug #53913 (Streams functions assume HAVE_GLOB is defined). (Chris Jones) . Fixed bug #53903 (userspace stream stat callback does not separate the Modified: php/php-src/branches/PHP_5_3/ext/standard/ftp_fopen_wrapper.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/standard/ftp_fopen_wrapper.c 2011-02-27 20:10:08 UTC (rev 308733) +++ php/php-src/branches/PHP_5_3/ext/standard/ftp_fopen_wrapper.c 2011-02-27 20:23:54 UTC (rev 308734) @@ -72,6 +72,12 @@ #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_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 @@ 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 @@ php_stream_write_string(controlstream, "QUIT\r\n"); php_stream_close(controlstream); - if (stream) { - stream->wrapperdata = NULL; - } + stream->wrapperthis = NULL; } return ret; @@ -584,7 +584,7 @@ } /* remember control stream */ - datastream->wrapperdata = (zval *)stream; + datastream->wrapperthis = stream; php_url_free(resource); return datastream; @@ -608,11 +608,13 @@ 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; } @@ -656,13 +658,18 @@ */ 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; @@ -688,6 +695,7 @@ 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]; @@ -747,12 +755,15 @@ 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) { php_url_free(resource); Modified: php/php-src/trunk/ext/standard/ftp_fopen_wrapper.c =================================================================== --- php/php-src/trunk/ext/standard/ftp_fopen_wrapper.c 2011-02-27 20:10:08 UTC (rev 308733) +++ php/php-src/trunk/ext/standard/ftp_fopen_wrapper.c 2011-02-27 20:23:54 UTC (rev 308734) @@ -72,6 +72,12 @@ #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_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 @@ 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 @@ 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 @@ } /* remember control stream */ - datastream->wrapperdata = (zval *)stream; + datastream->wrapperthis = stream; php_url_free(resource); return datastream; @@ -607,11 +607,13 @@ 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 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 @@ 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,12 +754,15 @@ 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) { php_url_free(resource);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php