]> granicus.if.org Git - php/commitdiff
Fix string.strip_tags filter
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 5 Jul 2018 17:08:00 +0000 (19:08 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 5 Jul 2018 17:08:00 +0000 (19:08 +0200)
Was segfaulting if no allowed tags are specified and performing an
out of bounds read if they were.

ext/standard/filters.c
ext/standard/tests/filters/strip_tags_filter.phpt [new file with mode: 0644]

index 90adc63536b5e8f9d6168277cb622411ebc54c95..7115c534b0679d9950683991905b6d88475e3592 100644 (file)
@@ -176,14 +176,14 @@ typedef struct _php_strip_tags_filter {
        int persistent;
 } php_strip_tags_filter;
 
-static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, const char *allowed_tags, size_t allowed_tags_len, int persistent)
+static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, zend_string *allowed_tags, int persistent)
 {
        if (allowed_tags != NULL) {
-               if (NULL == (inst->allowed_tags = pemalloc(allowed_tags_len, persistent))) {
+               if (NULL == (inst->allowed_tags = pemalloc(ZSTR_LEN(allowed_tags) + 1, persistent))) {
                        return FAILURE;
                }
-               memcpy((char *)inst->allowed_tags, allowed_tags, allowed_tags_len);
-               inst->allowed_tags_len = (int)allowed_tags_len;
+               memcpy((char *)inst->allowed_tags, ZSTR_VAL(allowed_tags), ZSTR_LEN(allowed_tags) + 1);
+               inst->allowed_tags_len = (int)ZSTR_LEN(allowed_tags);
        } else {
                inst->allowed_tags = NULL;
        }
@@ -247,7 +247,8 @@ static php_stream_filter_ops strfilter_strip_tags_ops = {
 static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zval *filterparams, int persistent)
 {
        php_strip_tags_filter *inst;
-       smart_str tags_ss = {0};
+       php_stream_filter *filter = NULL;
+       zend_string *allowed_tags = NULL;;
 
        inst = pemalloc(sizeof(php_strip_tags_filter), persistent);
 
@@ -258,6 +259,7 @@ static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zv
 
        if (filterparams != NULL) {
                if (Z_TYPE_P(filterparams) == IS_ARRAY) {
+                       smart_str tags_ss = {0};
                        zval *tmp;
 
                        ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(filterparams), tmp) {
@@ -267,22 +269,23 @@ static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zv
                                smart_str_appendc(&tags_ss, '>');
                        } ZEND_HASH_FOREACH_END();
                        smart_str_0(&tags_ss);
+                       allowed_tags = tags_ss.s;
                } else {
-                       /* FIXME: convert_to_* may clutter zvals and lead it into segfault ? */
-                       convert_to_string_ex(filterparams);
-                       smart_str_setl(&tags_ss, Z_STRVAL_P(filterparams), Z_STRLEN_P(filterparams));
+                       allowed_tags = zval_get_string(filterparams);
                }
        }
 
-       if (php_strip_tags_filter_ctor(inst, ZSTR_VAL(tags_ss.s), ZSTR_LEN(tags_ss.s), persistent) != SUCCESS) {
-               smart_str_free(&tags_ss);
+       if (php_strip_tags_filter_ctor(inst, allowed_tags, persistent) == SUCCESS) {
+               filter = php_stream_filter_alloc(&strfilter_strip_tags_ops, inst, persistent);
+       } else {
                pefree(inst, persistent);
-               return NULL;
        }
 
-       smart_str_free(&tags_ss);
+       if (allowed_tags) {
+               zend_string_release(allowed_tags);
+       }
 
-       return php_stream_filter_alloc(&strfilter_strip_tags_ops, inst, persistent);
+       return filter;
 }
 
 static php_stream_filter_factory strfilter_strip_tags_factory = {
diff --git a/ext/standard/tests/filters/strip_tags_filter.phpt b/ext/standard/tests/filters/strip_tags_filter.phpt
new file mode 100644 (file)
index 0000000..038545a
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+string.strip_tags filter
+--FILE--
+<?php
+$fp = fopen('php://output', 'w');
+stream_filter_append($fp, 'string.strip_tags');
+fwrite($fp, "test <b>bold</b> <i>italic</i> test\n");
+fclose($fp);
+
+$fp = fopen('php://output', 'w');
+stream_filter_append($fp, 'string.strip_tags', STREAM_FILTER_WRITE, "<b>");
+fwrite($fp, "test <b>bold</b> <i>italic</i> test\n");
+fclose($fp);
+
+$fp = fopen('php://output', 'w');
+stream_filter_append($fp, 'string.strip_tags', STREAM_FILTER_WRITE, ["b"]);
+fwrite($fp, "test <b>bold</b> <i>italic</i> test\n");
+fclose($fp);
+
+?>
+--EXPECT--
+test bold italic test
+test <b>bold</b> italic test
+test <b>bold</b> italic test