@@ -167,18 +167,48 @@ PHP_METHOD(XSLTProcessor, importStylesheet)
167167 xsltStylesheetPtr sheetp ;
168168 bool clone_docu = false;
169169 xmlNode * nodep = NULL ;
170- zval * cloneDocu , rv , clone_zv ;
170+ zval * cloneDocu , rv , clone_zv , owner_zv ;
171171 zend_string * member ;
172172
173173 id = ZEND_THIS ;
174174 if (zend_parse_parameters (ZEND_NUM_ARGS (), "o" , & docp ) == FAILURE ) {
175175 RETURN_THROWS ();
176176 }
177177
178+ nodep = php_libxml_import_node (docp );
179+ if (nodep == NULL ) {
180+ zend_argument_type_error (1 , "must be a valid XML node" );
181+ RETURN_THROWS ();
182+ }
183+
184+ if (Z_OBJ_HANDLER_P (docp , clone_obj ) == NULL ) {
185+ zend_argument_type_error (1 , "must be a cloneable node" );
186+ RETURN_THROWS ();
187+ }
188+
189+ ZVAL_UNDEF (& owner_zv );
190+
191+ /* For non-document nodes, resolve the ownerDocument and clone that
192+ * instead as xsltParseStylesheetProcess may free nodes in the document. */
193+ if (nodep -> type != XML_DOCUMENT_NODE && nodep -> type != XML_HTML_DOCUMENT_NODE ) {
194+ if (nodep -> doc == NULL ) {
195+ zend_argument_value_error (1 , "must be part of a document" );
196+ RETURN_THROWS ();
197+ }
198+
199+ /* See dom_import_simplexml_common */
200+
201+ dom_object * nodeobj = (dom_object * ) ((char * ) Z_OBJ_P (docp ) - Z_OBJ_HT_P (docp )-> offset );
202+
203+ php_dom_create_object ((xmlNodePtr ) nodep -> doc , & owner_zv , nodeobj );
204+ docp = & owner_zv ;
205+ }
206+
178207 /* libxslt uses _private, so we must copy the imported
179208 * stylesheet document otherwise the node proxies will be a mess.
180209 * We will clone the object and detach the libxml internals later. */
181210 zend_object * clone = Z_OBJ_HANDLER_P (docp , clone_obj )(Z_OBJ_P (docp ));
211+ zval_ptr_dtor (& owner_zv );
182212 if (!clone ) {
183213 RETURN_THROWS ();
184214 }
0 commit comments