summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-07-05 19:08:00 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-07-05 19:08:00 +0200
commit791f07e4f06a943bd7892bdc539a7313fb3d6d1e (patch)
treea65c7bc05d3ecdaaa7c82519a65a6d138982c20f
parentc97b8bbf8252c3a493a44bcb91fb137952f03710 (diff)
downloadphp-git-791f07e4f06a943bd7892bdc539a7313fb3d6d1e.tar.gz
Fix string.strip_tags filter
Was segfaulting if no allowed tags are specified and performing an out of bounds read if they were.
-rw-r--r--ext/standard/filters.c29
-rw-r--r--ext/standard/tests/filters/strip_tags_filter.phpt24
2 files changed, 40 insertions, 13 deletions
diff --git a/ext/standard/filters.c b/ext/standard/filters.c
index 90adc63536..7115c534b0 100644
--- a/ext/standard/filters.c
+++ b/ext/standard/filters.c
@@ -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
index 0000000000..038545ae6d
--- /dev/null
+++ b/ext/standard/tests/filters/strip_tags_filter.phpt
@@ -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