From f85e695409b44bcc18b2ff9354fc94d5538430a7 Mon Sep 17 00:00:00 2001 From: Rob Richards Date: Fri, 4 Aug 2006 18:11:27 +0000 Subject: [PATCH] add unicode support update test --- ext/dom/attr.c | 16 ++-- ext/dom/cdatasection.c | 4 +- ext/dom/characterdata.c | 16 ++-- ext/dom/comment.c | 4 +- ext/dom/document.c | 159 +++++++++++++++++++++++++------- ext/dom/documentfragment.c | 2 +- ext/dom/domimplementation.c | 4 +- ext/dom/element.c | 47 +++++----- ext/dom/entity.c | 6 +- ext/dom/entityreference.c | 3 +- ext/dom/namednodemap.c | 4 +- ext/dom/node.c | 136 +++++++++++++++++++++------ ext/dom/notation.c | 8 +- ext/dom/processinginstruction.c | 11 +-- ext/dom/tests/bug34276.phpt | 8 ++ ext/dom/text.c | 6 +- ext/dom/xpath.c | 5 +- 17 files changed, 309 insertions(+), 130 deletions(-) diff --git a/ext/dom/attr.c b/ext/dom/attr.c index 355b6c572f..f7b1c1596f 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -55,12 +55,12 @@ PHP_METHOD(domattr, __construct) int name_len, value_len, name_valid; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_attr_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s&", &id, dom_attr_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); name_valid = xmlValidateName((xmlChar *) name, 0); @@ -69,7 +69,7 @@ PHP_METHOD(domattr, __construct) RETURN_FALSE; } - nodep = xmlNewProp(NULL, (xmlChar *) name, value); + nodep = xmlNewProp(NULL, (xmlChar *) name, (xmlChar *) value); if (!nodep) { php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); @@ -105,7 +105,7 @@ int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC) } ALLOC_ZVAL(*retval); - ZVAL_STRING(*retval, (char *) (attrp->name), 1); + ZVAL_XML_STRING(*retval, (char *) (attrp->name), ZSTR_DUPLICATE); return SUCCESS; } @@ -152,10 +152,10 @@ int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC) if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) { - ZVAL_STRING(*retval, content, 1); + ZVAL_XML_STRING(*retval, (char *)content, ZSTR_DUPLICATE); xmlFree(content); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; @@ -184,10 +184,10 @@ int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } - xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + xmlNodeSetContentLen((xmlNodePtr) attrp, (xmlChar *) Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); if (newval == &value_copy) { zval_dtor(newval); diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c index 7d997fd4e2..eb8e4e8c60 100644 --- a/ext/dom/cdatasection.c +++ b/ext/dom/cdatasection.c @@ -51,12 +51,12 @@ PHP_METHOD(domcdatasection, __construct) int value_len; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_cdatasection_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_cdatasection_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + nodep = xmlNewCDataBlock(NULL, (xmlChar *) value, value_len); if (!nodep) { diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c index b45578e1e9..52169939d6 100644 --- a/ext/dom/characterdata.c +++ b/ext/dom/characterdata.c @@ -64,10 +64,10 @@ int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if ((content = xmlNodeGetContent(nodep)) != NULL) { - ZVAL_STRING(*retval, content, 1); + ZVAL_XML_STRING(*retval, content, ZSTR_DUPLICATE); xmlFree(content); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; @@ -91,7 +91,7 @@ int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); @@ -181,10 +181,10 @@ PHP_FUNCTION(dom_characterdata_substring_data) xmlFree(cur); if (substring) { - RETVAL_STRING(substring, 1); + RETVAL_XML_STRING(substring, ZSTR_DUPLICATE); xmlFree(substring); } else { - RETVAL_EMPTY_STRING(); + RETVAL_EMPTY_TEXT(); } } /* }}} end dom_characterdata_substring_data */ @@ -202,7 +202,7 @@ PHP_FUNCTION(dom_characterdata_append_data) char *arg; int arg_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_characterdata_class_entry, &arg, &arg_len, UG(utf8_conv)) == FAILURE) { return; } @@ -229,7 +229,7 @@ PHP_FUNCTION(dom_characterdata_insert_data) int length, arg_len; dom_object *intern; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols&", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len, UG(utf8_conv)) == FAILURE) { return; } @@ -334,7 +334,7 @@ PHP_FUNCTION(dom_characterdata_replace_data) int length, arg_len; dom_object *intern; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls&", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len, UG(utf8_conv)) == FAILURE) { return; } diff --git a/ext/dom/comment.c b/ext/dom/comment.c index c4653d7419..805e1432f4 100644 --- a/ext/dom/comment.c +++ b/ext/dom/comment.c @@ -51,12 +51,12 @@ PHP_METHOD(domcomment, __construct) int value_len; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_comment_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s&", &id, dom_comment_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + nodep = xmlNewComment((xmlChar *) value); if (!nodep) { diff --git a/ext/dom/document.c b/ext/dom/document.c index 4b3fabc1c1..914b1e18f4 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -194,7 +194,7 @@ int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (encoding != NULL) { - ZVAL_STRING(*retval, encoding, 1); + ZVAL_XML_STRING(*retval, encoding, ZSTR_DUPLICATE); } else { ZVAL_NULL(*retval); } @@ -221,7 +221,7 @@ int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval)); @@ -334,7 +334,7 @@ int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (version != NULL) { - ZVAL_STRING(*retval, version, 1); + ZVAL_XML_STRING(*retval, version, ZSTR_DUPLICATE); } else { ZVAL_NULL(*retval); } @@ -364,7 +364,7 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval)); @@ -699,7 +699,7 @@ int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); url = (char *) docp->URL; if (url != NULL) { - ZVAL_STRING(*retval, url, 1); + ZVAL_XML_STRING(*retval, url, ZSTR_DUPLICATE); } else { ZVAL_NULL(*retval); } @@ -729,7 +729,7 @@ int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval)); @@ -774,7 +774,7 @@ PHP_FUNCTION(dom_document_create_element) int ret, name_len, value_len; char *name, *value = NULL; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s&", &id, dom_document_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -836,7 +836,7 @@ PHP_FUNCTION(dom_document_create_text_node) dom_object *intern; char *value; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -865,7 +865,7 @@ PHP_FUNCTION(dom_document_create_comment) dom_object *intern; char *value; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -894,7 +894,7 @@ PHP_FUNCTION(dom_document_create_cdatasection) dom_object *intern; char *value; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -923,7 +923,7 @@ PHP_FUNCTION(dom_document_create_processing_instruction) dom_object *intern; char *name, *value = NULL; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s&", &id, dom_document_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -959,7 +959,7 @@ PHP_FUNCTION(dom_document_create_attribute) dom_object *intern; char *name; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -994,7 +994,7 @@ PHP_FUNCTION(dom_document_create_entity_reference) int ret, name_len; char *name; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1028,7 +1028,7 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name) char *name; xmlChar *local; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1101,7 +1101,7 @@ PHP_FUNCTION(dom_document_create_element_ns) int errorcode; dom_object *intern; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&|s&", &id, dom_document_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1165,7 +1165,7 @@ PHP_FUNCTION(dom_document_create_attribute_ns) dom_object *intern; int errorcode; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_document_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1228,7 +1228,7 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns) char *uri, *name; xmlChar *local, *nsuri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&", &id, dom_document_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1256,7 +1256,7 @@ PHP_FUNCTION(dom_document_get_element_by_id) dom_object *intern; char *idname; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_document_class_entry, &idname, &idname_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1327,12 +1327,12 @@ PHP_METHOD(domdocument, __construct) int encoding_len = 0, version_len = 0, refcount; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s&s&", &id, dom_document_class_entry, &version, &version_len, UG(utf8_conv), &encoding, &encoding_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + docp = xmlNewDoc(version); if (!docp) { @@ -1531,6 +1531,7 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { dom_object *intern; char *source; int source_len, refcount, ret; + zend_uchar source_type = IS_STRING; long options = 0; id = getThis(); @@ -1538,8 +1539,14 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { id = NULL; } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) { - return; + if (mode == DOM_LOAD_FILE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|l", &source, &source_len, &source_type, &options) == FAILURE) { + return; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) { + return; + } } if (!source_len) { @@ -1547,8 +1554,18 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { RETURN_FALSE; } + if (source_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &source, &source_len, (UChar*)source, source_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + newdoc = dom_document_parser(id, mode, source, options TSRMLS_CC); + if (source_type == IS_UNICODE) { + efree(source); + } + if (!newdoc) RETURN_FALSE; @@ -1611,9 +1628,10 @@ PHP_FUNCTION(dom_document_save) dom_object *intern; dom_doc_propsptr doc_props; char *file; + zend_uchar file_type; long options = 0; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ot|l", &id, dom_document_class_entry, &file, &file_len, &file_type, &options) == FAILURE) { return; } @@ -1632,7 +1650,19 @@ PHP_FUNCTION(dom_document_save) saveempty = xmlSaveNoEmptyTags; xmlSaveNoEmptyTags = 1; } + + if (file_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &file, &file_len, (UChar*)file, file_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + bytes = xmlSaveFormatFileEnc(file, docp, NULL, format); + + if (file_type == IS_UNICODE) { + efree(file); + } + if (options & LIBXML_SAVE_NOEMPTYTAG) { xmlSaveNoEmptyTags = saveempty; } @@ -1708,7 +1738,7 @@ PHP_FUNCTION(dom_document_savexml) if (!size) { RETURN_FALSE; } - RETVAL_RT_STRINGL(mem, size, 1); + RETVAL_STRINGL(mem, size, 1); xmlFree(mem); } } @@ -1838,9 +1868,16 @@ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) xmlSchemaValidCtxtPtr vptr; int is_valid; char resolved_path[MAXPATHLEN + 1]; + zend_uchar source_type = IS_STRING; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { - return; + if (type == DOM_LOAD_FILE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len, &source_type) == FAILURE) { + return; + } + } else { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } } if (source_len == 0) { @@ -1852,12 +1889,25 @@ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) switch (type) { case DOM_LOAD_FILE: + if (source_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &source, &source_len, (UChar*)source, source_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); if (!valid_file) { + if (source_type == IS_UNICODE) { + efree(source); + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source"); RETURN_FALSE; } parser = xmlSchemaNewParserCtxt(valid_file); + + if (source_type == IS_UNICODE) { + efree(source); + } break; case DOM_LOAD_STRING: parser = xmlSchemaNewMemParserCtxt(source, source_len); @@ -1928,9 +1978,16 @@ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) xmlRelaxNGValidCtxtPtr vptr; int is_valid; char resolved_path[MAXPATHLEN + 1]; + zend_uchar source_type = IS_STRING; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { - return; + if (type == DOM_LOAD_FILE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len, &source_type) == FAILURE) { + return; + } + } else { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } } if (source_len == 0) { @@ -1942,12 +1999,23 @@ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) switch (type) { case DOM_LOAD_FILE: + if (source_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &source, &source_len, (UChar*)source, source_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); if (!valid_file) { + if (source_type == IS_UNICODE) { + efree(source); + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source"); RETURN_FALSE; } parser = xmlRelaxNGNewParserCtxt(valid_file); + if (source_type == IS_UNICODE) { + efree(source); + } break; case DOM_LOAD_STRING: parser = xmlRelaxNGNewMemParserCtxt(source, source_len); @@ -2017,11 +2085,18 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) char *source; int source_len, refcount, ret; htmlParserCtxtPtr ctxt; - + zend_uchar source_type = IS_STRING; + id = getThis(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { - return; + if (mode == DOM_LOAD_FILE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len, &source_type) == FAILURE) { + return; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { + return; + } } if (!source_len) { @@ -2030,7 +2105,17 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) } if (mode == DOM_LOAD_FILE) { + if (source_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &source, &source_len, (UChar*)source, source_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + ctxt = htmlCreateFileParserCtxt(source, NULL); + + if (source_type == IS_UNICODE) { + efree(source); + } } else { source_len = xmlStrlen(source); ctxt = htmlCreateMemoryParserCtxt(source, source_len); @@ -2109,6 +2194,7 @@ PHP_FUNCTION(dom_document_save_html_file) dom_object *intern; dom_doc_propsptr doc_props; char *file; + zend_uchar file_type = IS_STRING; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) { return; @@ -2121,12 +2207,23 @@ PHP_FUNCTION(dom_document_save_html_file) DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + if (file_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &file, &file_len, (UChar*)file, file_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + /* encoding handled by property on doc */ doc_props = dom_get_doc_props(intern->document); format = doc_props->formatoutput; + bytes = htmlSaveFileFormat(file, docp, NULL, format); + if (file_type == IS_UNICODE) { + efree(file); + } + if (bytes == -1) { RETURN_FALSE; } diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c index 1afc644fc1..b412bd9e8a 100644 --- a/ext/dom/documentfragment.c +++ b/ext/dom/documentfragment.c @@ -117,7 +117,7 @@ PHP_METHOD(domdocumentfragment, appendXML) { int err; xmlNodePtr lst; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_documentfragment_class_entry, &data, &data_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_documentfragment_class_entry, &data, &data_len, UG(utf8_conv)) == FAILURE) { return; } diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index f65da0572b..e1218f0a73 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -77,7 +77,7 @@ PHP_METHOD(domimplementation, createDocumentType) xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL; xmlURIPtr uri; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&s&", &name, &name_len, UG(utf8_conv), &publicid, &publicid_len, UG(utf8_conv), &systemid, &systemid_len, UG(utf8_conv)) == FAILURE) { return; } @@ -136,7 +136,7 @@ PHP_METHOD(domimplementation, createDocument) char *prefix = NULL, *localname = NULL; dom_object *doctobj; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&O", &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv), &node, dom_documenttype_class_entry) == FAILURE) { return; } diff --git a/ext/dom/element.c b/ext/dom/element.c index eecd1c962f..437e5c07fd 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -72,12 +72,12 @@ PHP_METHOD(domelement, __construct) xmlNsPtr nsptr = NULL; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s!&s&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv), &uri, &uri_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + name_valid = xmlValidateName((xmlChar *) name, 0); if (name_valid != 0) { php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); @@ -161,10 +161,10 @@ int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC) qname = xmlStrdup(ns->prefix); qname = xmlStrcat(qname, ":"); qname = xmlStrcat(qname, nodep->name); - ZVAL_STRING(*retval, qname, 1); + ZVAL_XML_STRING(*retval, qname, ZSTR_DUPLICATE); xmlFree(qname); } else { - ZVAL_STRING(*retval, (char *) nodep->name, 1); + ZVAL_XML_STRING(*retval, (char *) nodep->name, ZSTR_DUPLICATE); } return SUCCESS; @@ -210,9 +210,9 @@ PHP_FUNCTION(dom_element_get_attribute) value = xmlGetProp(nodep, name); if (value == NULL) { - RETURN_EMPTY_STRING(); + RETURN_EMPTY_TEXT(); } else { - RETVAL_STRING(value, 1); + RETVAL_XML_STRING(value, ZSTR_DUPLICATE); xmlFree(value); } } @@ -232,8 +232,7 @@ PHP_FUNCTION(dom_element_set_attribute) dom_object *intern; char *name, *value; - - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -278,7 +277,7 @@ PHP_FUNCTION(dom_element_remove_attribute) int name_len; char *name; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -322,7 +321,7 @@ PHP_FUNCTION(dom_element_get_attribute_node) dom_object *intern; char *name; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -452,7 +451,7 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name) char *name; xmlChar *local; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -479,7 +478,7 @@ PHP_FUNCTION(dom_element_get_attribute_ns) int uri_len = 0, name_len = 0; char *uri, *name, *strattr; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -488,18 +487,18 @@ PHP_FUNCTION(dom_element_get_attribute_ns) strattr = xmlGetNsProp(elemp, name, uri); if (strattr != NULL) { - RETVAL_STRING(strattr, 1); + RETVAL_XML_STRING(strattr, ZSTR_DUPLICATE); xmlFree(strattr); } else { if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { nsptr = dom_get_nsdecl(elemp, name); if (nsptr != NULL) { - RETVAL_STRING((char *) nsptr->href, 1); + RETVAL_XML_STRING((char *) nsptr->href, ZSTR_DUPLICATE); } else { - RETVAL_EMPTY_STRING(); + RETVAL_EMPTY_TEXT(); } } else { - RETVAL_EMPTY_STRING(); + RETVAL_EMPTY_TEXT(); } } @@ -559,7 +558,7 @@ PHP_FUNCTION(dom_element_set_attribute_ns) dom_object *intern; int errorcode = 0, stricterror, is_xmlns = 0; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!ss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { return; } @@ -668,7 +667,7 @@ PHP_FUNCTION(dom_element_remove_attribute_ns) int name_len, uri_len; char *name, *uri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -725,7 +724,7 @@ PHP_FUNCTION(dom_element_get_attribute_node_ns) int uri_len, name_len, ret; char *uri, *name; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -827,7 +826,7 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns) char *uri, *name; xmlChar *local, *nsuri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -855,7 +854,7 @@ PHP_FUNCTION(dom_element_has_attribute) char *name, *value; int name_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -885,7 +884,7 @@ PHP_FUNCTION(dom_element_has_attribute_ns) int uri_len, name_len; char *uri, *name, *value; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv)) == FAILURE) { return; } @@ -942,7 +941,7 @@ PHP_FUNCTION(dom_element_set_id_attribute) int name_len; zend_bool is_id; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osb", &id, dom_element_class_entry, &name, &name_len, &is_id) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&b", &id, dom_element_class_entry, &name, &name_len, UG(utf8_conv), &is_id) == FAILURE) { return; } @@ -979,7 +978,7 @@ PHP_FUNCTION(dom_element_set_id_attribute_ns) char *uri, *name; zend_bool is_id; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossb", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &is_id) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&b", &id, dom_element_class_entry, &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv), &is_id) == FAILURE) { return; } diff --git a/ext/dom/entity.c b/ext/dom/entity.c index de3dfd1b57..71641e615f 100644 --- a/ext/dom/entity.c +++ b/ext/dom/entity.c @@ -59,7 +59,7 @@ int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { ZVAL_NULL(*retval); } else { - ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->ExternalID), ZSTR_DUPLICATE); } return SUCCESS; @@ -89,7 +89,7 @@ int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { ZVAL_NULL(*retval); } else { - ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->SystemID), ZSTR_DUPLICATE); } return SUCCESS; @@ -121,7 +121,7 @@ int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC) ZVAL_NULL(*retval); } else { content = xmlNodeGetContent((xmlNodePtr) nodep); - ZVAL_STRING(*retval, content, 1); + ZVAL_XML_STRING(*retval, content, ZSTR_DUPLICATE); xmlFree(content); } diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c index 53ec62548a..e5cf6fe1db 100644 --- a/ext/dom/entityreference.c +++ b/ext/dom/entityreference.c @@ -51,11 +51,10 @@ PHP_METHOD(domentityreference, __construct) int name_len, name_valid; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_entityreference_class_entry, &name, &name_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_entityreference_class_entry, &name, &name_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); name_valid = xmlValidateName((xmlChar *) name, 0); diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c index 1f7b80204f..280b1bd61b 100644 --- a/ext/dom/namednodemap.c +++ b/ext/dom/namednodemap.c @@ -107,7 +107,7 @@ PHP_FUNCTION(dom_namednodemap_get_named_item) xmlNodePtr nodep; xmlNotation *notep = NULL; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_namednodemap_class_entry, &named, &namedlen) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_namednodemap_class_entry, &named, &namedlen, UG(utf8_conv)) == FAILURE) { return; } @@ -243,7 +243,7 @@ PHP_FUNCTION(dom_namednodemap_get_named_item_ns) xmlNodePtr nodep; xmlNotation *notep = NULL; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_namednodemap_class_entry, &uri, &urilen, &named, &namedlen) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!&s&", &id, dom_namednodemap_class_entry, &uri, &urilen, UG(utf8_conv), &named, &namedlen, UG(utf8_conv)) == FAILURE) { return; } diff --git a/ext/dom/node.c b/ext/dom/node.c index 92785130f4..90f0b067a5 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -150,7 +150,7 @@ int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if(str != NULL) { - ZVAL_RT_STRING(*retval, str, 1); + ZVAL_XML_STRING(*retval, str, ZSTR_DUPLICATE); } else { ZVAL_EMPTY_TEXT(*retval); } @@ -205,7 +205,7 @@ int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if(str != NULL) { - ZVAL_RT_STRING(*retval, str, 1); + ZVAL_XML_STRING(*retval, str, ZSTR_DUPLICATE); xmlFree(str); } else { ZVAL_NULL(*retval); @@ -245,7 +245,7 @@ int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); if (newval == &value_copy) { @@ -619,7 +619,7 @@ int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if(str != NULL) { - ZVAL_STRING(*retval, str, 1); + ZVAL_XML_STRING(*retval, str, ZSTR_DUPLICATE); } else { ZVAL_NULL(*retval); } @@ -666,9 +666,9 @@ int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (str == NULL) { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } else { - ZVAL_STRING(*retval, str, 1); + ZVAL_XML_STRING(*retval, str, ZSTR_DUPLICATE); } return SUCCESS; @@ -705,7 +705,7 @@ int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC) zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } prefix = Z_STRVAL_P(newval); if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) { @@ -774,7 +774,7 @@ int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) { - ZVAL_STRING(*retval, (char *) (nodep->name), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->name), ZSTR_DUPLICATE); } else { ZVAL_NULL(*retval); } @@ -807,7 +807,7 @@ int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC) baseuri = xmlNodeGetBase(nodep->doc, nodep); if (baseuri) { - ZVAL_STRING(*retval, (char *) (baseuri), 1); + ZVAL_XML_STRING(*retval, (char *) (baseuri), ZSTR_DUPLICATE); xmlFree(baseuri); } else { ZVAL_NULL(*retval); @@ -842,10 +842,10 @@ int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if(str != NULL) { - ZVAL_STRING(*retval, str, 1); + ZVAL_XML_STRING(*retval, str, ZSTR_DUPLICATE); xmlFree(str); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; @@ -1530,7 +1530,7 @@ PHP_FUNCTION(dom_node_lookup_prefix) int uri_len = 0; char *uri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_node_class_entry, &uri, &uri_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1558,7 +1558,8 @@ PHP_FUNCTION(dom_node_lookup_prefix) if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) { if (nsptr->prefix != NULL) { - RETURN_STRING((char *) nsptr->prefix, 1); + RETVAL_XML_STRING((char *) nsptr->prefix, ZSTR_DUPLICATE); + return; } } } @@ -1581,7 +1582,7 @@ PHP_FUNCTION(dom_node_is_default_namespace) int uri_len = 0; char *uri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_node_class_entry, &uri, &uri_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1612,7 +1613,7 @@ PHP_FUNCTION(dom_node_lookup_namespace_uri) int prefix_len = 0; char *prefix; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_node_class_entry, &prefix, &prefix_len, UG(utf8_conv)) == FAILURE) { return; } @@ -1621,7 +1622,8 @@ PHP_FUNCTION(dom_node_lookup_namespace_uri) if (prefix_len > 0) { nsptr = xmlSearchNs(nodep->doc, nodep, prefix); if (nsptr && nsptr->href != NULL) { - RETURN_STRING((char *) nsptr->href, 1); + RETVAL_XML_STRING((char *) nsptr->href, ZSTR_DUPLICATE); + return; } } @@ -1689,6 +1691,7 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) xmlOutputBufferPtr buf; xmlXPathContextPtr ctxp=NULL; xmlXPathObjectPtr xpathobjp=NULL; + zend_uchar file_type = IS_STRING; if (mode == 0) { if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), @@ -1698,7 +1701,7 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) } } else { if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), - "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive, + "Ot|bba!a!", &id, dom_node_class_entry, &file, &file_len, &file_type, &exclusive, &with_comments, &xpath_array, &ns_prefixes) == FAILURE) { return; } @@ -1713,6 +1716,12 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) RETURN_FALSE; } + if (file_type == IS_UNICODE) { + if (php_stream_path_encode(NULL, &file, &file_len, (UChar*)file, file_len, REPORT_ERRORS, NULL) == FAILURE) { + RETURN_FALSE; + } + } + if (xpath_array == NULL) { if (nodep->type != XML_DOCUMENT_NODE) { ctxp = xmlXPathNewContext(docp); @@ -1726,6 +1735,9 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) xmlXPathFreeObject(xpathobjp); } xmlXPathFreeContext(ctxp); + if (file_type == IS_UNICODE) { + efree(file); + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset."); RETURN_FALSE; } @@ -1733,13 +1745,24 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) } else { /*xpath query from xpath_array */ HashTable *ht = Z_ARRVAL_P(xpath_array); - zval **tmp; + zval **tmp, **zxquery; char *xquery; + int xquery_len; if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS && - Z_TYPE_PP(tmp) == IS_STRING) { - xquery = Z_STRVAL_PP(tmp); + Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + zxquery = tmp; +/* + if (Z_TYPE_PP(tmp) == IS_STRING) { + xquery = Z_STRVAL_PP(tmp); + } else { + + } +*/ } else { + if (file_type == IS_UNICODE) { + efree(file); + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string"); RETURN_FALSE; } @@ -1750,26 +1773,66 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_ARRAY) { zval **tmpns; + char *nschar; + int nschar_len; + while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) { - if (Z_TYPE_PP(tmpns) == IS_STRING) { - char *prefix; + if (Z_TYPE_PP(tmpns) == IS_STRING || Z_TYPE_PP(tmpns) == IS_UNICODE) { + zstr prefix = NULL_ZSTR; ulong idx; - int prefix_key_len; + uint prefix_key_len; + zend_uchar htype; + UErrorCode errCode = 0; + + if (Z_TYPE_PP(tmpns) == IS_UNICODE) { + zend_convert_from_unicode(UG(utf8_conv), &nschar, &nschar_len, Z_USTRVAL_PP(tmpns), Z_USTRLEN_PP(tmpns), &errCode); + } else { + nschar = Z_STRVAL_PP(tmpns); + } + + htype = zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), + &prefix, &prefix_key_len, &idx, 0, NULL); + if (htype == HASH_KEY_IS_STRING) { + xmlXPathRegisterNs(ctxp, (xmlChar *)prefix.s, (xmlChar *)nschar); + } else + if (htype == HASH_KEY_IS_UNICODE) { + char *tmp_prefix; + int tmp_prefix_len; + errCode = 0; + + zend_convert_from_unicode(UG(utf8_conv), &tmp_prefix, &tmp_prefix_len, prefix.u, prefix_key_len, &errCode); + xmlXPathRegisterNs(ctxp, (xmlChar *)tmp_prefix, (xmlChar *)nschar); + efree(tmp_prefix); + } - if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), - &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) { - xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns)); + if (Z_TYPE_PP(tmpns) == IS_UNICODE) { + efree(nschar); } } zend_hash_move_forward(Z_ARRVAL_PP(tmp)); } } + if (Z_TYPE_PP(zxquery) == IS_UNICODE) { + UErrorCode errCode = 0; + zend_convert_from_unicode(UG(utf8_conv), &xquery, &xquery_len, Z_USTRVAL_PP(zxquery), Z_USTRLEN_PP(zxquery), &errCode); + } else { + xquery = Z_STRVAL_PP(zxquery); + } + xpathobjp = xmlXPathEvalExpression(xquery, ctxp); + + if (Z_TYPE_PP(zxquery) == IS_UNICODE) { + efree(xquery); + } + ctxp->node = NULL; if (xpathobjp && xpathobjp->type == XPATH_NODESET) { nodeset = xpathobjp->nodesetval; } else { + if (file_type == IS_UNICODE) { + efree(file); + } if (xpathobjp) { xmlXPathFreeObject(xpathobjp); } @@ -1788,7 +1851,14 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) sizeof(xmlChar *), 0); while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) { if (Z_TYPE_PP(tmpns) == IS_STRING) { - inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns); + inclusive_ns_prefixes[nscount++] = estrndup(Z_STRVAL_PP(tmpns), strlen(Z_STRVAL_PP(tmpns))); + } else { + UErrorCode errCode = 0; + char *prefix; + int prfeix_len; + + zend_convert_from_unicode(UG(utf8_conv), &prefix, &prfeix_len, Z_USTRVAL_PP(tmpns), Z_USTRLEN_PP(tmpns), &errCode); + inclusive_ns_prefixes[nscount++] = prefix; } zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes)); } @@ -1810,7 +1880,15 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) with_comments, buf); } + if (file_type == IS_UNICODE) { + efree(file); + } + if (inclusive_ns_prefixes != NULL) { + int nscount = 0; + while(inclusive_ns_prefixes[nscount] != NULL) { + efree(inclusive_ns_prefixes[nscount++]); + } efree(inclusive_ns_prefixes); } if (xpathobjp != NULL) { @@ -1873,11 +1951,11 @@ PHP_METHOD(domnode, getNodePath) DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); - value = xmlGetNodePath(nodep); + value = (char *)xmlGetNodePath(nodep); if (value == NULL) { RETURN_NULL(); } else { - RETVAL_STRING(value, 1); + RETVAL_XML_STRING(value, ZSTR_DUPLICATE); xmlFree(value); } diff --git a/ext/dom/notation.c b/ext/dom/notation.c index ed1e73c032..4fdda426e9 100644 --- a/ext/dom/notation.c +++ b/ext/dom/notation.c @@ -59,9 +59,9 @@ int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (nodep->ExternalID) { - ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->ExternalID), ZSTR_DUPLICATE); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; @@ -89,9 +89,9 @@ int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); if (nodep->SystemID) { - ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->SystemID), ZSTR_DUPLICATE); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c index a948b9603c..ac663db95b 100644 --- a/ext/dom/processinginstruction.c +++ b/ext/dom/processinginstruction.c @@ -51,11 +51,10 @@ PHP_METHOD(domprocessinginstruction, __construct) int name_len, value_len, name_valid; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_processinginstruction_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s&", &id, dom_processinginstruction_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); name_valid = xmlValidateName((xmlChar *) name, 0); @@ -99,7 +98,7 @@ int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_ } ALLOC_ZVAL(*retval); - ZVAL_STRING(*retval, (char *) (nodep->name), 1); + ZVAL_XML_STRING(*retval, (char *) (nodep->name), ZSTR_DUPLICATE); return SUCCESS; } @@ -129,10 +128,10 @@ int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC if ((content = xmlNodeGetContent(nodep)) != NULL) { - ZVAL_STRING(*retval, content, 1); + ZVAL_XML_STRING(*retval, content, ZSTR_DUPLICATE); xmlFree(content); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_EMPTY_TEXT(*retval); } return SUCCESS; @@ -156,7 +155,7 @@ int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC zval_copy_ctor(&value_copy); newval = &value_copy; } - convert_to_string(newval); + convert_to_string_with_converter(newval, UG(utf8_conv)); } xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); diff --git a/ext/dom/tests/bug34276.phpt b/ext/dom/tests/bug34276.phpt index 4a63943f7a..fac4b85e7f 100644 --- a/ext/dom/tests/bug34276.phpt +++ b/ext/dom/tests/bug34276.phpt @@ -41,3 +41,11 @@ string(8) "attrbnew" string(5) "attrc" +--UEXPECT-- +bool(false) +unicode(0) "" +unicode(8) "attranew" +unicode(8) "attrbnew" +unicode(5) "attrc" + + diff --git a/ext/dom/text.c b/ext/dom/text.c index 9124de9ea5..8923efe007 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -55,12 +55,12 @@ PHP_METHOD(domtext, __construct) int value_len; php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_text_class_entry, &value, &value_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s&", &id, dom_text_class_entry, &value, &value_len, UG(utf8_conv)) == FAILURE) { php_std_error_handling(); return; } - php_std_error_handling(); + nodep = xmlNewText((xmlChar *) value); if (!nodep) { @@ -98,7 +98,7 @@ int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC) ALLOC_ZVAL(*retval); wholetext = xmlNodeListGetString(node->doc, node, 1); - ZVAL_STRING(*retval, wholetext, 1); + ZVAL_XML_STRING(*retval, wholetext, ZSTR_DUPLICATE); xmlFree(wholetext); diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 6148880b80..d0885d1eb0 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -111,7 +111,7 @@ PHP_FUNCTION(dom_xpath_register_ns) dom_object *intern; unsigned char *prefix, *ns_uri; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&", &id, dom_xpath_class_entry, &prefix, &prefix_len, UG(utf8_conv), &ns_uri, &ns_uri_len, UG(utf8_conv)) == FAILURE) { return; } @@ -150,8 +150,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) { xmlDoc *docp = NULL; xmlNsPtr *ns; - - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|O", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|O", &id, dom_xpath_class_entry, &expr, &expr_len, UG(utf8_conv), &context, dom_node_class_entry) == FAILURE) { return; } -- 2.50.1