lbarnaud Thu Jan 8 17:03:42 2009 UTC Added files: (Branch: PHP_5_2) /php-src/ext/standard/tests/filters filter_errors_convert_base64_decode.phpt filter_errors.inc filter_errors_user.phpt filter_errors_zlib_inflate.phpt
Modified files: /php-src/ext/standard streamsfuncs.c /php-src/main/streams filter.c php_stream_filter_api.h /php-src NEWS Log: MFH: Fixed error conditions handling in stream_filter_append()
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.c?r1=1.58.2.6.2.30&r2=1.58.2.6.2.31&diff_format=u Index: php-src/ext/standard/streamsfuncs.c diff -u php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.30 php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.31 --- php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.30 Wed Dec 31 11:17:45 2008 +++ php-src/ext/standard/streamsfuncs.c Thu Jan 8 17:03:42 2009 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c,v 1.58.2.6.2.30 2008/12/31 11:17:45 sebastian Exp $ */ +/* $Id: streamsfuncs.c,v 1.58.2.6.2.31 2009/01/08 17:03:42 lbarnaud Exp $ */ #include "php.h" #include "php_globals.h" @@ -1083,6 +1083,7 @@ long read_write = 0; zval *filterparams = NULL; php_stream_filter *filter = NULL; + int ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz", &zstream, &filtername, &filternamelen, &read_write, &filterparams) == FAILURE) { @@ -1112,9 +1113,13 @@ } if (append) { - php_stream_filter_append(&stream->readfilters, filter); + ret = php_stream_filter_append_ex(&stream->readfilters, filter TSRMLS_CC); } else { - php_stream_filter_prepend(&stream->readfilters, filter); + ret = php_stream_filter_prepend_ex(&stream->readfilters, filter TSRMLS_CC); + } + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1 TSRMLS_CC); + RETURN_FALSE; } } @@ -1125,9 +1130,13 @@ } if (append) { - php_stream_filter_append(&stream->writefilters, filter); + ret = php_stream_filter_append_ex(&stream->writefilters, filter TSRMLS_CC); } else { - php_stream_filter_prepend(&stream->writefilters, filter); + ret = php_stream_filter_prepend_ex(&stream->writefilters, filter TSRMLS_CC); + } + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1 TSRMLS_CC); + RETURN_FALSE; } } http://cvs.php.net/viewvc.cgi/php-src/main/streams/filter.c?r1=1.17.2.3.2.13&r2=1.17.2.3.2.14&diff_format=u Index: php-src/main/streams/filter.c diff -u php-src/main/streams/filter.c:1.17.2.3.2.13 php-src/main/streams/filter.c:1.17.2.3.2.14 --- php-src/main/streams/filter.c:1.17.2.3.2.13 Wed Dec 31 11:17:48 2008 +++ php-src/main/streams/filter.c Thu Jan 8 17:03:42 2009 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filter.c,v 1.17.2.3.2.13 2008/12/31 11:17:48 sebastian Exp $ */ +/* $Id: filter.c,v 1.17.2.3.2.14 2009/01/08 17:03:42 lbarnaud Exp $ */ #include "php.h" #include "php_globals.h" @@ -313,7 +313,7 @@ pefree(filter, filter->is_persistent); } -PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) { filter->next = chain->head; filter->prev = NULL; @@ -325,9 +325,16 @@ } chain->head = filter; filter->chain = chain; + + return SUCCESS; } -PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +{ + php_stream_filter_prepend_ex(chain, filter TSRMLS_CC); +} + +PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) { php_stream *stream = chain->stream; @@ -349,7 +356,7 @@ php_stream_bucket *bucket; size_t consumed = 0; - bucket = php_stream_bucket_new(stream, stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0 TSRMLS_CC); + bucket = php_stream_bucket_new(stream, (char*) stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0 TSRMLS_CC); php_stream_bucket_append(brig_inp, bucket TSRMLS_CC); status = filter->fops->filter(stream, filter, brig_inp, brig_outp, &consumed, PSFS_FLAG_NORMAL TSRMLS_CC); @@ -360,19 +367,18 @@ switch (status) { case PSFS_ERR_FATAL: - /* If this first cycle simply fails then there's something wrong with the filter. - Pull the filter off the chain and leave the read buffer alone. */ - if (chain->head == filter) { - chain->head = NULL; - chain->tail = NULL; - } else { - filter->prev->next = NULL; - chain->tail = filter->prev; + while (brig_in.head) { + bucket = brig_in.head; + php_stream_bucket_unlink(bucket TSRMLS_CC); + php_stream_bucket_delref(bucket TSRMLS_CC); } - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter failed to process pre-buffered data. Not adding to filterchain."); - break; + while (brig_out.head) { + bucket = brig_out.head; + php_stream_bucket_unlink(bucket TSRMLS_CC); + php_stream_bucket_delref(bucket TSRMLS_CC); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter failed to process pre-buffered data"); + return FAILURE; case PSFS_FEED_ME: /* We don't actually need data yet, leave this filter in a feed me state until data is needed. @@ -406,6 +412,20 @@ } } + return SUCCESS; +} + +PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +{ + if (php_stream_filter_append_ex(chain, filter TSRMLS_CC) != SUCCESS) { + if (chain->head == filter) { + chain->head = NULL; + chain->tail = NULL; + } else { + filter->prev->next = NULL; + chain->tail = filter->prev; + } + } } PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC) http://cvs.php.net/viewvc.cgi/php-src/main/streams/php_stream_filter_api.h?r1=1.13.2.1.2.4&r2=1.13.2.1.2.5&diff_format=u Index: php-src/main/streams/php_stream_filter_api.h diff -u php-src/main/streams/php_stream_filter_api.h:1.13.2.1.2.4 php-src/main/streams/php_stream_filter_api.h:1.13.2.1.2.5 --- php-src/main/streams/php_stream_filter_api.h:1.13.2.1.2.4 Wed Dec 31 11:17:48 2008 +++ php-src/main/streams/php_stream_filter_api.h Thu Jan 8 17:03:42 2009 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_filter_api.h,v 1.13.2.1.2.4 2008/12/31 11:17:48 sebastian Exp $ */ +/* $Id: php_stream_filter_api.h,v 1.13.2.1.2.5 2009/01/08 17:03:42 lbarnaud Exp $ */ /* The filter API works on the principle of "Bucket-Brigades". This is * partially inspired by the Apache 2 method of doing things, although @@ -125,7 +125,9 @@ /* stack filter onto a stream */ BEGIN_EXTERN_C() PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); +PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); +PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC); PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC); PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC); http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.1382&r2=1.2027.2.547.2.1383&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.1382 php-src/NEWS:1.2027.2.547.2.1383 --- php-src/NEWS:1.2027.2.547.2.1382 Thu Jan 8 00:39:14 2009 +++ php-src/NEWS Thu Jan 8 17:03:42 2009 @@ -6,6 +6,7 @@ - Added optional sorting type flag parameter to array_unique(). Default is SORT_REGULAR. (Andrei) +- Fixed error conditions handling in stream_filter_append(). (Arnaud) - Fixed zip filename property read. (Pierre) - Fixed explode() behavior with empty string to respect negative limit. (Shire) - Fixed security issue in imagerotate(), background colour isn't validated http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/filters/filter_errors_convert_base64_decode.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/filters/filter_errors_convert_base64_decode.phpt +++ php-src/ext/standard/tests/filters/filter_errors_convert_base64_decode.phpt --TEST-- Filter errors: convert.base64-decode --SKIPIF-- <?php require 'filter_errors.inc'; filter_errors_skipif('convert.base64-decode'); ?> --FILE-- <?php require 'filter_errors.inc'; filter_errors_test('convert.base64-decode', '==='); ?> --EXPECTF-- test filtering of buffered data Warning: stream_filter_append(): stream filter (convert.base64-decode): invalid byte sequence in %s Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/filters/filter_errors.inc?view=markup&rev=1.1 Index: php-src/ext/standard/tests/filters/filter_errors.inc +++ php-src/ext/standard/tests/filters/filter_errors.inc <?php function filter_errors_skipif($needle) { $filters = stream_get_filters(); foreach($filters as $filter) { if (fnmatch($filter, $needle)) return; } die("skip $needle not available"); } function filter_errors_test($filter, $data) { echo "test filtering of buffered data\n"; $stream = fopen('php://memory', 'wb+'); fwrite($stream, b".\r\n$data"); fseek($stream, 0, SEEK_SET); stream_get_line($stream, 8192, "\r\n"); $f = stream_filter_append($stream, $filter); echo "test filtering of non buffered data\n"; $stream = fopen('php://memory', 'wb+'); fwrite($stream, b"$data"); fseek($stream, 0, SEEK_SET); stream_get_line($stream, 8192, "\r\n"); stream_get_contents($stream); } http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/filters/filter_errors_user.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/filters/filter_errors_user.phpt +++ php-src/ext/standard/tests/filters/filter_errors_user.phpt --TEST-- Filter errors: user filter --FILE-- <?php require 'filter_errors.inc'; class test_filter0 extends php_user_filter { function filter($in, $out, &$consumed, $closing) { return PSFS_ERR_FATAL; } } class test_filter1 extends php_user_filter { function filter($in, $out, &$consumed, $closing) { $bucket = stream_bucket_make_writeable($in); return PSFS_ERR_FATAL; } } class test_filter2 extends php_user_filter { function filter($in, $out, &$consumed, $closing) { while ($bucket = stream_bucket_make_writeable($in)) { $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_ERR_FATAL; } } class test_filter3 extends php_user_filter { function filter($in, $out, &$consumed, $closing) { $bucket = stream_bucket_new($this->stream, "42"); stream_bucket_append($out, $bucket); return PSFS_ERR_FATAL; } } class test_filter4 extends php_user_filter { function filter($in, $out, &$consumed, $closing) { $bucket = stream_bucket_new($this->stream, "42"); return PSFS_ERR_FATAL; } } for($i = 0; $i < 5; ++$i) { echo "test_filter$i\n"; var_dump(stream_filter_register("test_filter$i", "test_filter$i")); filter_errors_test("test_filter$i", "42"); } ?> --EXPECTF-- test_filter0 bool(true) test filtering of buffered data Warning: stream_filter_append(): Unprocessed filter buckets remaining on input brigade in %s Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data test_filter1 bool(true) test filtering of buffered data Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data test_filter2 bool(true) test filtering of buffered data Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data test_filter3 bool(true) test filtering of buffered data Warning: stream_filter_append(): Unprocessed filter buckets remaining on input brigade in %s Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data test_filter4 bool(true) test filtering of buffered data Warning: stream_filter_append(): Unprocessed filter buckets remaining on input brigade in %s Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/filters/filter_errors_zlib_inflate.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/filters/filter_errors_zlib_inflate.phpt +++ php-src/ext/standard/tests/filters/filter_errors_zlib_inflate.phpt --TEST-- Filter errors: zlib.inflate --SKIPIF-- <?php require 'filter_errors.inc'; filter_errors_skipif('zlib.inflate'); ?> --FILE-- <?php require 'filter_errors.inc'; filter_errors_test('zlib.inflate', gzencode(b'42')); ?> --EXPECTF-- test filtering of buffered data Warning: stream_filter_append(): Filter failed to process pre-buffered data in %s test filtering of non buffered data
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php