mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Fixed for Bug #26384 (domxslt->process causes segfault with xsl:key)
This commit is contained in:
parent
e57b75eff4
commit
5c039bbad9
3 changed files with 49 additions and 18 deletions
|
@ -113,6 +113,7 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
|
||||||
intern->ptr = NULL;
|
intern->ptr = NULL;
|
||||||
intern->prop_handler = NULL;
|
intern->prop_handler = NULL;
|
||||||
intern->parameter = NULL;
|
intern->parameter = NULL;
|
||||||
|
intern->hasKeys = 0;
|
||||||
|
|
||||||
ALLOC_HASHTABLE(intern->std.properties);
|
ALLOC_HASHTABLE(intern->std.properties);
|
||||||
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||||
|
@ -145,6 +146,10 @@ PHP_MINIT_FUNCTION(xsl)
|
||||||
xsltRegisterExtModuleFunction ((const xmlChar *) "function",
|
xsltRegisterExtModuleFunction ((const xmlChar *) "function",
|
||||||
(const xmlChar *) "http://php.net/xsl",
|
(const xmlChar *) "http://php.net/xsl",
|
||||||
xsl_ext_function_object_php);
|
xsl_ext_function_object_php);
|
||||||
|
|
||||||
|
REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO", 0, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER", -1, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS", 1, CONST_CS | CONST_PERSISTENT);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@ typedef struct _xsl_object {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
HashTable *prop_handler;
|
HashTable *prop_handler;
|
||||||
zend_object_handle handle;
|
zend_object_handle handle;
|
||||||
HashTable *parameter;
|
HashTable *parameter;
|
||||||
|
int hasKeys;
|
||||||
} xsl_object;
|
} xsl_object;
|
||||||
|
|
||||||
void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
|
void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
|
||||||
|
@ -72,8 +73,8 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
|
||||||
RETURN_FALSE; \
|
RETURN_FALSE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PHP_MINIT_FUNCTION(xsl);
|
PHP_MINIT_FUNCTION(xsl);
|
||||||
PHP_MSHUTDOWN_FUNCTION(xsl);
|
PHP_MSHUTDOWN_FUNCTION(xsl);
|
||||||
PHP_RINIT_FUNCTION(xsl);
|
PHP_RINIT_FUNCTION(xsl);
|
||||||
|
|
|
@ -129,8 +129,11 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
|
||||||
xsltStylesheetPtr sheetp, oldsheetp;
|
xsltStylesheetPtr sheetp, oldsheetp;
|
||||||
xsl_object *intern;
|
xsl_object *intern;
|
||||||
php_libxml_node_object *docobj;
|
php_libxml_node_object *docobj;
|
||||||
int prevSubstValue, prevExtDtdValue;
|
int prevSubstValue, prevExtDtdValue, clone_docu;
|
||||||
|
xmlNode *nodep;
|
||||||
|
zend_object_handlers *std_hnd;
|
||||||
|
zval *cloneDocu, *member;
|
||||||
|
|
||||||
DOM_GET_THIS(id);
|
DOM_GET_THIS(id);
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
|
||||||
|
@ -143,10 +146,10 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
|
||||||
stylesheet document otherwise the node proxies will be a mess */
|
stylesheet document otherwise the node proxies will be a mess */
|
||||||
newdoc = xmlCopyDoc(doc, 1);
|
newdoc = xmlCopyDoc(doc, 1);
|
||||||
xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
|
xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
|
||||||
|
|
||||||
prevSubstValue = xmlSubstituteEntitiesDefault(1);
|
prevSubstValue = xmlSubstituteEntitiesDefault(1);
|
||||||
prevExtDtdValue = xmlLoadExtDtdDefaultValue;
|
prevExtDtdValue = xmlLoadExtDtdDefaultValue;
|
||||||
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
|
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
|
||||||
|
|
||||||
sheetp = xsltParseStylesheetDoc(newdoc);
|
sheetp = xsltParseStylesheetDoc(newdoc);
|
||||||
xmlSubstituteEntitiesDefault(prevSubstValue);
|
xmlSubstituteEntitiesDefault(prevSubstValue);
|
||||||
xmlLoadExtDtdDefaultValue = prevExtDtdValue;
|
xmlLoadExtDtdDefaultValue = prevExtDtdValue;
|
||||||
|
@ -157,6 +160,28 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
|
||||||
}
|
}
|
||||||
|
|
||||||
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
||||||
|
|
||||||
|
std_hnd = zend_get_std_object_handlers();
|
||||||
|
MAKE_STD_ZVAL(member);
|
||||||
|
ZVAL_STRING(member, "cloneDocument", 0);
|
||||||
|
cloneDocu = std_hnd->read_property(id, member, 1 TSRMLS_CC);
|
||||||
|
convert_to_long(cloneDocu);
|
||||||
|
efree(member);
|
||||||
|
clone_docu = Z_LVAL_P(cloneDocu);
|
||||||
|
if (clone_docu == 0) {
|
||||||
|
/* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
|
||||||
|
nodep = xmlDocGetRootElement(sheetp->doc)->children;
|
||||||
|
while (nodep) {
|
||||||
|
if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
|
||||||
|
intern->hasKeys = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nodep = nodep->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intern->hasKeys = clone_docu;
|
||||||
|
}
|
||||||
|
|
||||||
if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
|
if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
|
||||||
/* free wrapper */
|
/* free wrapper */
|
||||||
if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
|
if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
|
||||||
|
@ -181,7 +206,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
|
||||||
xmlDoc *doc = NULL;
|
xmlDoc *doc = NULL;
|
||||||
xmlDoc *newdocp;
|
xmlDoc *newdocp;
|
||||||
xsltStylesheetPtr sheetp;
|
xsltStylesheetPtr sheetp;
|
||||||
int ret, clone = 0;
|
int ret, clone;
|
||||||
char **params = NULL;
|
char **params = NULL;
|
||||||
xsl_object *intern;
|
xsl_object *intern;
|
||||||
php_libxml_node_object *docobj;
|
php_libxml_node_object *docobj;
|
||||||
|
@ -190,7 +215,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
|
||||||
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
||||||
sheetp = (xsltStylesheetPtr) intern->ptr;
|
sheetp = (xsltStylesheetPtr) intern->ptr;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &docp, &clone) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
|
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
|
||||||
|
@ -199,11 +224,11 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
|
||||||
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
doc = xmlCopyDoc(doc, 1);
|
doc = xmlCopyDoc(doc, 1);
|
||||||
}
|
}
|
||||||
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
|
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +258,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
|
||||||
xmlDoc *doc = NULL;
|
xmlDoc *doc = NULL;
|
||||||
xmlDoc *newdocp;
|
xmlDoc *newdocp;
|
||||||
xsltStylesheetPtr sheetp;
|
xsltStylesheetPtr sheetp;
|
||||||
int ret, uri_len, clone = 0;
|
int ret, uri_len, clone;
|
||||||
char **params = NULL, *uri;
|
char **params = NULL, *uri;
|
||||||
xsl_object *intern;
|
xsl_object *intern;
|
||||||
php_libxml_node_object *docobj;
|
php_libxml_node_object *docobj;
|
||||||
|
@ -242,7 +267,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
|
||||||
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
||||||
sheetp = (xsltStylesheetPtr) intern->ptr;
|
sheetp = (xsltStylesheetPtr) intern->ptr;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os|l", &docp, &uri, &uri_len, &clone) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &docp, &uri, &uri_len) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,13 +277,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
|
||||||
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
doc = xmlCopyDoc(doc, 1);
|
doc = xmlCopyDoc(doc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
|
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
|
||||||
|
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +314,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
|
||||||
xmlDoc *doc = NULL;
|
xmlDoc *doc = NULL;
|
||||||
xmlDoc *newdocp;
|
xmlDoc *newdocp;
|
||||||
xsltStylesheetPtr sheetp;
|
xsltStylesheetPtr sheetp;
|
||||||
int ret, clone = 0;
|
int ret, clone;
|
||||||
xmlChar *doc_txt_ptr;
|
xmlChar *doc_txt_ptr;
|
||||||
int doc_txt_len;
|
int doc_txt_len;
|
||||||
char **params = NULL;
|
char **params = NULL;
|
||||||
|
@ -300,7 +325,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
|
||||||
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
|
||||||
sheetp = (xsltStylesheetPtr) intern->ptr;
|
sheetp = (xsltStylesheetPtr) intern->ptr;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &docp, &clone) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
|
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
|
||||||
|
@ -309,13 +334,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
|
||||||
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
doc = xmlCopyDoc(doc, 1);
|
doc = xmlCopyDoc(doc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
|
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
|
||||||
|
|
||||||
if (clone == 1) {
|
if (intern->hasKeys == 1) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue