summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Wallner <mike@php.net>2005-10-25 18:04:59 +0000
committerMichael Wallner <mike@php.net>2005-10-25 18:04:59 +0000
commita329ecd8c456103708db74d1760b52c9721390b2 (patch)
treee3be0c966dca99abb65ed8128d72f1cb0f59cab0
parent2af3190a3d17de08cf7af0a1f015addb6202998f (diff)
downloadphp-git-a329ecd8c456103708db74d1760b52c9721390b2.tar.gz
fix bug #34965 tidy is not binary safe
-rw-r--r--NEWS1
-rw-r--r--ext/tidy/tests/018.phpt16
-rw-r--r--ext/tidy/tidy.c104
3 files changed, 83 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index 4179552053..3307c6bfa8 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ PHP NEWS
- Fixed fgetcsv() and fputcsv() inconsistency. (Dmitry)
- Fixed bug #34968 (bz2 extension fails on to build on some win32 setups).
(Ilia)
+- Fixed bug #34965 (tidy is not binary safe). (Mike)
- Fixed bug #34957 (PHP doesn't respect ACLs for access checks). (Wez)
- Fixed bug #34950 (Unable to get WSDL through proxy). (Dmitry)
- Fixed bug #34938 (dns_get_record() doesn't resolve long hostnames and
diff --git a/ext/tidy/tests/018.phpt b/ext/tidy/tests/018.phpt
new file mode 100644
index 0000000000..405a46d42b
--- /dev/null
+++ b/ext/tidy/tests/018.phpt
@@ -0,0 +1,16 @@
+--TEST--
+binary safety
+--SKIPIF--
+<?php if (!extension_loaded("tidy")) print "skip"; ?>
+--FILE--
+<?php
+$x = tidy_repair_string("<p>abra\0cadabra</p>",
+ array( 'show-body-only' => true,
+ 'clean' => false,
+ 'newline' => "\n")
+ );
+var_dump($x);
+?>
+--EXPECT--
+string(19) "<p>abracadabra</p>
+"
diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c
index 5bd8d7da75..326996b32f 100644
--- a/ext/tidy/tidy.c
+++ b/ext/tidy/tidy.c
@@ -127,6 +127,18 @@
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
}
+#define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \
+ { \
+ zval *tmp; \
+ MAKE_STD_ZVAL(tmp); \
+ if (_string) { \
+ ZVAL_STRINGL(tmp, (char *)_string, _len, 1); \
+ } else { \
+ ZVAL_EMPTY_STRING(tmp); \
+ } \
+ zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
+ }
+
#define ADD_PROPERTY_LONG(_table, _key, _long) \
{ \
zval *tmp; \
@@ -198,7 +210,7 @@ struct _PHPTidyObj {
/* {{{ ext/tidy prototypes
*/
-static char *php_tidy_file_to_mem(char *, zend_bool TSRMLS_DC);
+static char *php_tidy_file_to_mem(char *, zend_bool, int * TSRMLS_DC);
static void tidy_object_free_storage(void * TSRMLS_DC);
static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC);
static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
@@ -405,7 +417,7 @@ static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS
static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file)
{
char *data=NULL, *arg1, *enc = NULL;
- int arg1_len, enc_len = 0;
+ int arg1_len, enc_len = 0, data_len = 0;
zend_bool use_include_path = 0;
TidyDoc doc;
TidyBuffer *errbuf;
@@ -418,11 +430,12 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
}
if (is_file) {
- if (!(data = php_tidy_file_to_mem(arg1, use_include_path TSRMLS_CC))) {
+ if (!(data = php_tidy_file_to_mem(arg1, use_include_path, &data_len TSRMLS_CC))) {
RETURN_FALSE;
}
} else {
data = arg1;
+ data_len = arg1_len;
}
doc = tidyCreate();
@@ -464,7 +477,12 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
}
if (data) {
- if (tidyParseString(doc, data) < 0) {
+ TidyBuffer buf = {0};
+
+ tidyBufInit(&buf);
+ tidyBufAppend(&buf, data, data_len);
+
+ if (tidyParseBuffer(doc, &buf) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
RETVAL_FALSE;
} else {
@@ -472,12 +490,14 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
TidyBuffer output = {0};
tidySaveBuffer (doc, &output);
- RETVAL_STRING(output.bp, 1);
+ RETVAL_STRINGL(output.bp, output.size-1, 1);
tidyBufFree(&output);
} else {
RETVAL_FALSE;
}
}
+
+ tidyBufFree(&buf);
}
if (is_file) {
@@ -489,17 +509,17 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
tidyRelease(doc);
}
-static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path TSRMLS_DC)
+static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, int *len TSRMLS_DC)
{
php_stream *stream;
- int len;
char *data = NULL;
if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE, NULL))) {
return NULL;
}
- if ((len = php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
+ if ((*len = (int) php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
data = estrdup("");
+ *len = 0;
}
php_stream_close(stream);
@@ -647,7 +667,7 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type, int free TSRMLS_
case IS_STRING:
obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
tidySaveBuffer (obj->ptdoc->doc, &output);
- ZVAL_STRINGL(out, output.bp, output.size, TRUE);
+ ZVAL_STRINGL(out, output.bp, output.size-1, TRUE);
tidyBufFree(&output);
break;
@@ -679,7 +699,7 @@ static int tidy_node_cast_handler(zval *in, zval *out, int type, int free TSRMLS
case IS_STRING:
obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
- ZVAL_STRINGL(out, buf.bp, buf.size, TRUE);
+ ZVAL_STRINGL(out, buf.bp, buf.size-1, TRUE);
tidyBufFree(&buf);
break;
@@ -700,7 +720,7 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
if (output.size) {
MAKE_STD_ZVAL(temp);
- ZVAL_STRINGL(temp, output.bp, output.size, TRUE);
+ ZVAL_STRINGL(temp, output.bp, output.size-1, TRUE);
zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL);
}
@@ -708,7 +728,7 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
if (obj->ptdoc->errbuf->size) {
MAKE_STD_ZVAL(temp);
- ZVAL_STRINGL(temp, obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size, TRUE);
+ ZVAL_STRINGL(temp, obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, TRUE);
zend_hash_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer"), (void *)&temp, sizeof(zval *), NULL);
}
}
@@ -728,8 +748,7 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
memset(&buf, 0, sizeof(buf));
tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
- buf.bp[buf.size-1] = '\0';
- ADD_PROPERTY_STRING(obj->std.properties, value, buf.bp);
+ ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size-1);
tidyBufFree(&buf);
ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node));
@@ -891,8 +910,10 @@ static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRML
return SUCCESS;
}
-static int php_tidy_parse_string(PHPTidyObj *obj, char *string, char *enc TSRMLS_DC)
-{
+static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *enc TSRMLS_DC)
+{
+ TidyBuffer buf = {0};
+
if(enc) {
if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
@@ -900,18 +921,18 @@ static int php_tidy_parse_string(PHPTidyObj *obj, char *string, char *enc TSRMLS
}
}
- if (tidyParseString(obj->ptdoc->doc, string) < 0) {
+ tidyBufInit(&buf);
+ tidyBufAppend(&buf, string, len);
+ if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) {
+ tidyBufFree(&buf);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", obj->ptdoc->errbuf->bp);
return FAILURE;
- } else {
- tidy_doc_update_properties(obj TSRMLS_CC);
-
- return SUCCESS;
}
-
+ tidyBufFree(&buf);
tidy_doc_update_properties(obj TSRMLS_CC);
-
+
+ return SUCCESS;
}
static void tidy_globals_ctor(void *global TSRMLS_DC)
@@ -996,7 +1017,12 @@ PHP_FUNCTION(ob_tidyhandler)
TIDY_SET_DEFAULT_CONFIG(doc);
if (input_len > 1) {
- if (tidyParseString(doc, input) < 0 || tidyCleanAndRepair(doc) < 0) {
+ TidyBuffer buf = {0};
+
+ tidyBufInit(&buf);
+ tidyBufAppend(&buf, input, input_len);
+
+ if (tidyParseBuffer(doc, &buf) < 0 || tidyCleanAndRepair(doc) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf.bp);
RETVAL_NULL();
} else {
@@ -1004,10 +1030,12 @@ PHP_FUNCTION(ob_tidyhandler)
tidyBufInit(&output);
tidySaveBuffer(doc, &output);
- RETVAL_STRING(output.bp, 1);
+ RETVAL_STRINGL(output.bp, output.size-1, 1);
tidyBufFree(&output);
}
+
+ tidyBufFree(&buf);
} else {
RETVAL_NULL();
}
@@ -1037,7 +1065,7 @@ PHP_FUNCTION(tidy_parse_string)
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
- if(php_tidy_parse_string(obj, input, enc TSRMLS_CC) == FAILURE) {
+ if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == FAILURE) {
zval_dtor(return_value);
INIT_ZVAL(*return_value);
RETURN_FALSE;
@@ -1053,7 +1081,7 @@ PHP_FUNCTION(tidy_get_error_buffer)
TIDY_FETCH_OBJECT;
if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) {
- RETURN_STRING(obj->ptdoc->errbuf->bp, 1);
+ RETURN_STRINGL(obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, 1);
} else {
RETURN_FALSE;
}
@@ -1069,7 +1097,7 @@ PHP_FUNCTION(tidy_get_output)
tidySaveBuffer(obj->ptdoc->doc, &output);
- RETVAL_STRING(output.bp, 1);
+ RETVAL_STRINGL(output.bp, output.size-1, 1);
tidyBufFree(&output);
}
@@ -1080,7 +1108,7 @@ PHP_FUNCTION(tidy_get_output)
PHP_FUNCTION(tidy_parse_file)
{
char *inputfile, *enc = NULL;
- int input_len, enc_len = 0;
+ int input_len, contents_len, enc_len = 0;
zend_bool use_include_path = 0;
char *contents;
zval *options = NULL;
@@ -1096,14 +1124,14 @@ PHP_FUNCTION(tidy_parse_file)
tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
- if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path TSRMLS_CC))) {
+ if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
RETURN_FALSE;
}
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
- if(php_tidy_parse_string(obj, contents, enc TSRMLS_CC) == FAILURE) {
+ if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
zval_dtor(return_value);
INIT_ZVAL(*return_value);
RETVAL_FALSE;
@@ -1398,7 +1426,7 @@ PHP_FUNCTION(tidy_getopt)
TIDY_DOC_METHOD(__construct)
{
char *inputfile = NULL, *enc = NULL;
- int input_len = 0, enc_len = 0;
+ int input_len = 0, enc_len = 0, contents_len = 0;
zend_bool use_include_path = 0;
char *contents;
zval *options = NULL;
@@ -1414,14 +1442,14 @@ TIDY_DOC_METHOD(__construct)
obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
if (inputfile) {
- if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path TSRMLS_CC))) {
+ if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
return;
}
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
- php_tidy_parse_string(obj, contents, enc TSRMLS_CC);
+ php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC);
efree(contents);
}
@@ -1430,7 +1458,7 @@ TIDY_DOC_METHOD(__construct)
TIDY_DOC_METHOD(parseFile)
{
char *inputfile, *enc = NULL;
- int input_len, enc_len = 0;
+ int input_len, enc_len = 0, contents_len = 0;
zend_bool use_include_path = 0;
char *contents;
zval *options = NULL;
@@ -1445,14 +1473,14 @@ TIDY_DOC_METHOD(parseFile)
RETURN_FALSE;
}
- if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path TSRMLS_CC))) {
+ if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
RETURN_FALSE;
}
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
- if(php_tidy_parse_string(obj, contents, enc TSRMLS_CC) == FAILURE) {
+ if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
RETVAL_FALSE;
} else {
RETVAL_TRUE;
@@ -1478,7 +1506,7 @@ TIDY_DOC_METHOD(parseString)
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
- if(php_tidy_parse_string(obj, input, enc TSRMLS_CC) == SUCCESS) {
+ if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == SUCCESS) {
RETURN_TRUE;
}