Fixed for Bug #26384 (domxslt->process causes segfault with xsl:key)

This commit is contained in:
Christian Stocker 2003-11-29 16:37:37 +00:00
parent e57b75eff4
commit 5c039bbad9
3 changed files with 49 additions and 18 deletions

View File

@ -113,6 +113,7 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
intern->ptr = NULL;
intern->prop_handler = NULL;
intern->parameter = NULL;
intern->hasKeys = 0;
ALLOC_HASHTABLE(intern->std.properties);
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
@ -145,6 +146,10 @@ PHP_MINIT_FUNCTION(xsl)
xsltRegisterExtModuleFunction ((const xmlChar *) "function",
(const xmlChar *) "http://php.net/xsl",
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;
}

View File

@ -54,7 +54,8 @@ typedef struct _xsl_object {
void *ptr;
HashTable *prop_handler;
zend_object_handle handle;
HashTable *parameter;
HashTable *parameter;
int hasKeys;
} xsl_object;
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; \
}
PHP_MINIT_FUNCTION(xsl);
PHP_MSHUTDOWN_FUNCTION(xsl);
PHP_RINIT_FUNCTION(xsl);

View File

@ -129,8 +129,11 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
xsltStylesheetPtr sheetp, oldsheetp;
xsl_object *intern;
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);
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 */
newdoc = xmlCopyDoc(doc, 1);
xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
prevSubstValue = xmlSubstituteEntitiesDefault(1);
prevExtDtdValue = xmlLoadExtDtdDefaultValue;
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
sheetp = xsltParseStylesheetDoc(newdoc);
xmlSubstituteEntitiesDefault(prevSubstValue);
xmlLoadExtDtdDefaultValue = prevExtDtdValue;
@ -157,6 +160,28 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
}
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)) {
/* free wrapper */
if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
@ -181,7 +206,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
int ret, clone = 0;
int ret, clone;
char **params = NULL;
xsl_object *intern;
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);
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;
}
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);
}
if (clone == 1) {
if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
if (clone == 1) {
if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}
@ -233,7 +258,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
int ret, uri_len, clone = 0;
int ret, uri_len, clone;
char **params = NULL, *uri;
xsl_object *intern;
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);
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;
}
@ -252,13 +277,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
}
if (clone == 1) {
if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
if (clone == 1) {
if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}
@ -289,7 +314,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
int ret, clone = 0;
int ret, clone;
xmlChar *doc_txt_ptr;
int doc_txt_len;
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);
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;
}
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);
}
if (clone == 1) {
if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
if (clone == 1) {
if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}