diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c
index a94cc31d74c..406e468ac8a 100644
--- a/ext/dom/documenttype.c
+++ b/ext/dom/documenttype.c
@@ -188,8 +188,7 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_
{
xmlDtdPtr dtdptr;
- xmlDtd *intsubset;
- xmlOutputBuffer *buff = NULL;
+ xmlDtdPtr intsubset;
dtdptr = (xmlDtdPtr) dom_object_get_node(obj);
@@ -200,22 +199,37 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_
ALLOC_ZVAL(*retval);
- if (dtdptr->doc != NULL && ((intsubset = dtdptr->doc->intSubset) != NULL)) {
- buff = xmlAllocOutputBuffer(NULL);
- if (buff != NULL) {
- xmlNodeDumpOutput (buff, NULL, (xmlNodePtr) intsubset, 0, 0, NULL);
- xmlOutputBufferFlush(buff);
+ if (dtdptr->doc != NULL && ((intsubset = xmlGetIntSubset(dtdptr->doc)) != NULL) && intsubset->children != NULL) {
+ smart_str ret_buf = {0};
+ xmlNodePtr cur = intsubset->children;
+
+ while (cur != NULL) {
+ xmlOutputBuffer *buff = xmlAllocOutputBuffer(NULL);
+
+ if (buff != NULL) {
+ xmlNodeDumpOutput (buff, NULL, cur, 0, 0, NULL);
+ xmlOutputBufferFlush(buff);
+
#ifdef LIBXML2_NEW_BUFFER
- ZVAL_STRINGL(*retval, xmlOutputBufferGetContent(buff), xmlOutputBufferGetSize(buff), 1);
+ smart_str_appendl(ret_buf, xmlOutputBufferGetContent(buff), xmlOutputBufferGetSize(buff));
#else
- ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1);
+ smart_str_appendl(&ret_buf, buff->buffer->content, buff->buffer->use);
#endif
- (void)xmlOutputBufferClose(buff);
+
+ (void)xmlOutputBufferClose(buff);
+ }
+
+ cur = cur->next;
+ }
+
+ if (ret_buf.len) {
+ ZVAL_STRINGL(*retval, ret_buf.c, ret_buf.len, 1);
+ smart_str_free(&ret_buf);
return SUCCESS;
}
}
- ZVAL_EMPTY_STRING(*retval);
+ ZVAL_NULL(*retval);
return SUCCESS;
diff --git a/ext/dom/tests/DOMDocumentType_basic_001.phpt b/ext/dom/tests/DOMDocumentType_basic_001.phpt
index 8991ed97d47..6648a146ff6 100644
--- a/ext/dom/tests/DOMDocumentType_basic_001.phpt
+++ b/ext/dom/tests/DOMDocumentType_basic_001.phpt
@@ -43,6 +43,6 @@ print 'notation: '.$notation->nodeName."\n";
publicId: -//OASIS//DTD DocBook XML//EN
systemId: docbookx.dtd
name: chapter
-internalSubset:
+internalSubset:
entity: logo
-notation: gif
\ No newline at end of file
+notation: gif
diff --git a/ext/dom/tests/bug67081.phpt b/ext/dom/tests/bug67081.phpt
new file mode 100644
index 00000000000..56c2c8e58b5
--- /dev/null
+++ b/ext/dom/tests/bug67081.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #67081 DOMDocumentType->internalSubset returns entire DOCTYPE tag, not only the subset
+--SKIPIF--
+
+--FILE--
+load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_0.xml");
+ var_dump($domDocument->doctype->internalSubset);
+
+ $domDocument = new DOMDocument();
+ $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_1.xml");
+ var_dump($domDocument->doctype->internalSubset);
+
+ $domDocument = new DOMDocument();
+ $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug67081_2.xml");
+ var_dump($domDocument->doctype->internalSubset);
+
+ $domDocument = new DOMDocument();
+ $domDocument->load(dirname(__FILE__) . DIRECTORY_SEPARATOR . "dom.xml");
+ var_dump($domDocument->doctype->internalSubset);
+?>
+===DONE===
+--EXPECT--
+string(19) "
+"
+string(38) "
+
+"
+NULL
+string(277) "
+
+
+
+
+
+
+
+
+"
+===DONE===
diff --git a/ext/dom/tests/bug67081_0.xml b/ext/dom/tests/bug67081_0.xml
new file mode 100644
index 00000000000..604eea57b16
--- /dev/null
+++ b/ext/dom/tests/bug67081_0.xml
@@ -0,0 +1,6 @@
+
+
+]>
+
+
diff --git a/ext/dom/tests/bug67081_1.xml b/ext/dom/tests/bug67081_1.xml
new file mode 100644
index 00000000000..7ae542e977d
--- /dev/null
+++ b/ext/dom/tests/bug67081_1.xml
@@ -0,0 +1,7 @@
+
+
+
+]>
+
+
diff --git a/ext/dom/tests/bug67081_2.xml b/ext/dom/tests/bug67081_2.xml
new file mode 100644
index 00000000000..c10af0966ce
--- /dev/null
+++ b/ext/dom/tests/bug67081_2.xml
@@ -0,0 +1,5 @@
+
+
+
+