lbarnaud                Thu Jan  8 17:01:58 2009 UTC

  Added files:                 (Branch: PHP_5_3)
    /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 
  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.15.2.32&r2=1.58.2.6.2.15.2.33&diff_format=u
Index: php-src/ext/standard/streamsfuncs.c
diff -u php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.15.2.32 
php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.15.2.33
--- php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.15.2.32      Wed Dec 31 
11:15:45 2008
+++ php-src/ext/standard/streamsfuncs.c Thu Jan  8 17:01:58 2009
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: streamsfuncs.c,v 1.58.2.6.2.15.2.32 2008/12/31 11:15:45 sebastian Exp 
$ */
+/* $Id: streamsfuncs.c,v 1.58.2.6.2.15.2.33 2009/01/08 17:01:58 lbarnaud Exp $ 
*/
 
 #include "php.h"
 #include "php_globals.h"
@@ -1147,6 +1147,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) {
@@ -1176,9 +1177,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;
                }
        }
 
@@ -1189,9 +1194,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.10.2.3&r2=1.17.2.3.2.10.2.4&diff_format=u
Index: php-src/main/streams/filter.c
diff -u php-src/main/streams/filter.c:1.17.2.3.2.10.2.3 
php-src/main/streams/filter.c:1.17.2.3.2.10.2.4
--- php-src/main/streams/filter.c:1.17.2.3.2.10.2.3     Wed Dec 31 11:15:48 2008
+++ php-src/main/streams/filter.c       Thu Jan  8 17:01:58 2009
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: filter.c,v 1.17.2.3.2.10.2.3 2008/12/31 11:15:48 sebastian Exp $ */
+/* $Id: filter.c,v 1.17.2.3.2.10.2.4 2009/01/08 17:01:58 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.1.2.3&r2=1.13.2.1.2.1.2.4&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.1.2.3 
php-src/main/streams/php_stream_filter_api.h:1.13.2.1.2.1.2.4
--- php-src/main/streams/php_stream_filter_api.h:1.13.2.1.2.1.2.3       Wed Dec 
31 11:15:48 2008
+++ php-src/main/streams/php_stream_filter_api.h        Thu Jan  8 17:01:58 2009
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_stream_filter_api.h,v 1.13.2.1.2.1.2.3 2008/12/31 11:15:48 
sebastian Exp $ */
+/* $Id: php_stream_filter_api.h,v 1.13.2.1.2.1.2.4 2009/01/08 17:01:58 
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/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

Reply via email to