@@ -129,8 +129,11 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
129129 xsltStylesheetPtr sheetp , oldsheetp ;
130130 xsl_object * intern ;
131131 php_libxml_node_object * docobj ;
132- int prevSubstValue , prevExtDtdValue ;
133-
132+ int prevSubstValue , prevExtDtdValue , clone_docu ;
133+ xmlNode * nodep ;
134+ zend_object_handlers * std_hnd ;
135+ zval * cloneDocu , * member ;
136+
134137 DOM_GET_THIS (id );
135138
136139 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o" , & docp ) == FAILURE ) {
@@ -143,10 +146,10 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
143146 stylesheet document otherwise the node proxies will be a mess */
144147 newdoc = xmlCopyDoc (doc , 1 );
145148 xmlNodeSetBase ((xmlNodePtr ) newdoc , (xmlChar * )doc -> URL );
146-
147149 prevSubstValue = xmlSubstituteEntitiesDefault (1 );
148150 prevExtDtdValue = xmlLoadExtDtdDefaultValue ;
149151 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
152+
150153 sheetp = xsltParseStylesheetDoc (newdoc );
151154 xmlSubstituteEntitiesDefault (prevSubstValue );
152155 xmlLoadExtDtdDefaultValue = prevExtDtdValue ;
@@ -157,6 +160,28 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
157160 }
158161
159162 intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
163+
164+ std_hnd = zend_get_std_object_handlers ();
165+ MAKE_STD_ZVAL (member );
166+ ZVAL_STRING (member , "cloneDocument" , 0 );
167+ cloneDocu = std_hnd -> read_property (id , member , 1 TSRMLS_CC );
168+ convert_to_long (cloneDocu );
169+ efree (member );
170+ clone_docu = Z_LVAL_P (cloneDocu );
171+ if (clone_docu == 0 ) {
172+ /* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
173+ nodep = xmlDocGetRootElement (sheetp -> doc )-> children ;
174+ while (nodep ) {
175+ if (nodep -> type == XML_ELEMENT_NODE && xmlStrEqual (nodep -> name , "key" ) && xmlStrEqual (nodep -> ns -> href , XSLT_NAMESPACE )) {
176+ intern -> hasKeys = 1 ;
177+ break ;
178+ }
179+ nodep = nodep -> next ;
180+ }
181+ } else {
182+ intern -> hasKeys = clone_docu ;
183+ }
184+
160185 if ((oldsheetp = (xsltStylesheetPtr )intern -> ptr )) {
161186 /* free wrapper */
162187 if (((xsltStylesheetPtr ) intern -> ptr )-> _private != NULL ) {
@@ -181,7 +206,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
181206 xmlDoc * doc = NULL ;
182207 xmlDoc * newdocp ;
183208 xsltStylesheetPtr sheetp ;
184- int ret , clone = 0 ;
209+ int ret , clone ;
185210 char * * params = NULL ;
186211 xsl_object * intern ;
187212 php_libxml_node_object * docobj ;
@@ -190,7 +215,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
190215 intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
191216 sheetp = (xsltStylesheetPtr ) intern -> ptr ;
192217
193- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o|l " , & docp , & clone ) == FAILURE ) {
218+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o" , & docp ) == FAILURE ) {
194219 RETURN_FALSE ;
195220 }
196221 DOC_GET_OBJ (doc , docp , xmlDocPtr , docobj );
@@ -199,11 +224,11 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
199224 params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
200225 }
201226
202- if (clone == 1 ) {
227+ if (intern -> hasKeys == 1 ) {
203228 doc = xmlCopyDoc (doc , 1 );
204229 }
205230 newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * ) params );
206- if (clone == 1 ) {
231+ if (intern -> hasKeys == 1 ) {
207232 xmlFreeDoc (doc );
208233 }
209234
@@ -233,7 +258,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
233258 xmlDoc * doc = NULL ;
234259 xmlDoc * newdocp ;
235260 xsltStylesheetPtr sheetp ;
236- int ret , uri_len , clone = 0 ;
261+ int ret , uri_len , clone ;
237262 char * * params = NULL , * uri ;
238263 xsl_object * intern ;
239264 php_libxml_node_object * docobj ;
@@ -242,7 +267,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
242267 intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
243268 sheetp = (xsltStylesheetPtr ) intern -> ptr ;
244269
245- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "os|l " , & docp , & uri , & uri_len , & clone ) == FAILURE ) {
270+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "os" , & docp , & uri , & uri_len ) == FAILURE ) {
246271 RETURN_FALSE ;
247272 }
248273
@@ -252,13 +277,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
252277 params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
253278 }
254279
255- if (clone == 1 ) {
280+ if (intern -> hasKeys == 1 ) {
256281 doc = xmlCopyDoc (doc , 1 );
257282 }
258283
259284 newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * )params );
260285
261- if (clone == 1 ) {
286+ if (intern -> hasKeys == 1 ) {
262287 xmlFreeDoc (doc );
263288 }
264289
@@ -289,7 +314,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
289314 xmlDoc * doc = NULL ;
290315 xmlDoc * newdocp ;
291316 xsltStylesheetPtr sheetp ;
292- int ret , clone = 0 ;
317+ int ret , clone ;
293318 xmlChar * doc_txt_ptr ;
294319 int doc_txt_len ;
295320 char * * params = NULL ;
@@ -300,7 +325,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
300325 intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
301326 sheetp = (xsltStylesheetPtr ) intern -> ptr ;
302327
303- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o|l " , & docp , & clone ) == FAILURE ) {
328+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o" , & docp ) == FAILURE ) {
304329 RETURN_FALSE ;
305330 }
306331 DOC_GET_OBJ (doc , docp , xmlDocPtr , docobj );
@@ -309,13 +334,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
309334 params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
310335 }
311336
312- if (clone == 1 ) {
337+ if (intern -> hasKeys == 1 ) {
313338 doc = xmlCopyDoc (doc , 1 );
314339 }
315340
316341 newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * )params );
317342
318- if (clone == 1 ) {
343+ if (intern -> hasKeys == 1 ) {
319344 xmlFreeDoc (doc );
320345 }
321346
0 commit comments