@@ -129,8 +129,11 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
129
129
xsltStylesheetPtr sheetp , oldsheetp ;
130
130
xsl_object * intern ;
131
131
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
+
134
137
DOM_GET_THIS (id );
135
138
136
139
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "o" , & docp ) == FAILURE ) {
@@ -143,10 +146,10 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
143
146
stylesheet document otherwise the node proxies will be a mess */
144
147
newdoc = xmlCopyDoc (doc , 1 );
145
148
xmlNodeSetBase ((xmlNodePtr ) newdoc , (xmlChar * )doc -> URL );
146
-
147
149
prevSubstValue = xmlSubstituteEntitiesDefault (1 );
148
150
prevExtDtdValue = xmlLoadExtDtdDefaultValue ;
149
151
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
152
+
150
153
sheetp = xsltParseStylesheetDoc (newdoc );
151
154
xmlSubstituteEntitiesDefault (prevSubstValue );
152
155
xmlLoadExtDtdDefaultValue = prevExtDtdValue ;
@@ -157,6 +160,28 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
157
160
}
158
161
159
162
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
+
160
185
if ((oldsheetp = (xsltStylesheetPtr )intern -> ptr )) {
161
186
/* free wrapper */
162
187
if (((xsltStylesheetPtr ) intern -> ptr )-> _private != NULL ) {
@@ -181,7 +206,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
181
206
xmlDoc * doc = NULL ;
182
207
xmlDoc * newdocp ;
183
208
xsltStylesheetPtr sheetp ;
184
- int ret , clone = 0 ;
209
+ int ret , clone ;
185
210
char * * params = NULL ;
186
211
xsl_object * intern ;
187
212
php_libxml_node_object * docobj ;
@@ -190,7 +215,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
190
215
intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
191
216
sheetp = (xsltStylesheetPtr ) intern -> ptr ;
192
217
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 ) {
194
219
RETURN_FALSE ;
195
220
}
196
221
DOC_GET_OBJ (doc , docp , xmlDocPtr , docobj );
@@ -199,11 +224,11 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
199
224
params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
200
225
}
201
226
202
- if (clone == 1 ) {
227
+ if (intern -> hasKeys == 1 ) {
203
228
doc = xmlCopyDoc (doc , 1 );
204
229
}
205
230
newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * ) params );
206
- if (clone == 1 ) {
231
+ if (intern -> hasKeys == 1 ) {
207
232
xmlFreeDoc (doc );
208
233
}
209
234
@@ -233,7 +258,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
233
258
xmlDoc * doc = NULL ;
234
259
xmlDoc * newdocp ;
235
260
xsltStylesheetPtr sheetp ;
236
- int ret , uri_len , clone = 0 ;
261
+ int ret , uri_len , clone ;
237
262
char * * params = NULL , * uri ;
238
263
xsl_object * intern ;
239
264
php_libxml_node_object * docobj ;
@@ -242,7 +267,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
242
267
intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
243
268
sheetp = (xsltStylesheetPtr ) intern -> ptr ;
244
269
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 ) {
246
271
RETURN_FALSE ;
247
272
}
248
273
@@ -252,13 +277,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
252
277
params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
253
278
}
254
279
255
- if (clone == 1 ) {
280
+ if (intern -> hasKeys == 1 ) {
256
281
doc = xmlCopyDoc (doc , 1 );
257
282
}
258
283
259
284
newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * )params );
260
285
261
- if (clone == 1 ) {
286
+ if (intern -> hasKeys == 1 ) {
262
287
xmlFreeDoc (doc );
263
288
}
264
289
@@ -289,7 +314,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
289
314
xmlDoc * doc = NULL ;
290
315
xmlDoc * newdocp ;
291
316
xsltStylesheetPtr sheetp ;
292
- int ret , clone = 0 ;
317
+ int ret , clone ;
293
318
xmlChar * doc_txt_ptr ;
294
319
int doc_txt_len ;
295
320
char * * params = NULL ;
@@ -300,7 +325,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
300
325
intern = (xsl_object * )zend_object_store_get_object (id TSRMLS_CC );
301
326
sheetp = (xsltStylesheetPtr ) intern -> ptr ;
302
327
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 ) {
304
329
RETURN_FALSE ;
305
330
}
306
331
DOC_GET_OBJ (doc , docp , xmlDocPtr , docobj );
@@ -309,13 +334,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
309
334
params = php_xsl_xslt_make_params (intern -> parameter , 0 TSRMLS_CC );
310
335
}
311
336
312
- if (clone == 1 ) {
337
+ if (intern -> hasKeys == 1 ) {
313
338
doc = xmlCopyDoc (doc , 1 );
314
339
}
315
340
316
341
newdocp = xsltApplyStylesheet (sheetp , doc , (const char * * )params );
317
342
318
- if (clone == 1 ) {
343
+ if (intern -> hasKeys == 1 ) {
319
344
xmlFreeDoc (doc );
320
345
}
321
346
0 commit comments