1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Christian Stocker <chregu@php.net> |
16 | Rob Richards <rrichards@php.net> |
17 +----------------------------------------------------------------------+
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "php.h"
25 #if HAVE_LIBXML && HAVE_DOM
26 #include "php_dom.h"
27
28 /* {{{ arginfo */
29 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_get_feature, 0, 0, 2)
30 ZEND_ARG_INFO(0, feature)
31 ZEND_ARG_INFO(0, version)
32 ZEND_END_ARG_INFO();
33
34 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_has_feature, 0, 0, 0)
35 ZEND_END_ARG_INFO();
36
37 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_documenttype, 0, 0, 3)
38 ZEND_ARG_INFO(0, qualifiedName)
39 ZEND_ARG_INFO(0, publicId)
40 ZEND_ARG_INFO(0, systemId)
41 ZEND_END_ARG_INFO();
42
43 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_document, 0, 0, 3)
44 ZEND_ARG_INFO(0, namespaceURI)
45 ZEND_ARG_INFO(0, qualifiedName)
46 ZEND_ARG_OBJ_INFO(0, docType, DOMDocumentType, 0)
47 ZEND_END_ARG_INFO();
48 /* }}} */
49
50 /*
51 * class DOMImplementation
52 *
53 * URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-102161490
54 * Since:
55 */
56
57 const zend_function_entry php_dom_domimplementation_class_functions[] = {
58 PHP_ME(domimplementation, getFeature, arginfo_dom_implementation_get_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
59 PHP_ME(domimplementation, hasFeature, arginfo_dom_implementation_has_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
60 PHP_ME(domimplementation, createDocumentType, arginfo_dom_implementation_create_documenttype, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
61 PHP_ME(domimplementation, createDocument, arginfo_dom_implementation_create_document, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
62 PHP_FE_END
63 };
64
65 /* {{{ proto bool dom_domimplementation_has_feature(string feature, string version);
66 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7
67 Since:
68 */
PHP_METHOD(domimplementation,hasFeature)69 PHP_METHOD(domimplementation, hasFeature)
70 {
71 size_t feature_len, version_len;
72 char *feature, *version;
73
74 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &feature, &feature_len, &version, &version_len) == FAILURE) {
75 return;
76 }
77
78 if (dom_has_feature(feature, version)) {
79 RETURN_TRUE;
80 } else {
81 RETURN_FALSE;
82 }
83 }
84 /* }}} end dom_domimplementation_has_feature */
85
86 /* {{{ proto DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId);
87 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType
88 Since: DOM Level 2
89 */
PHP_METHOD(domimplementation,createDocumentType)90 PHP_METHOD(domimplementation, createDocumentType)
91 {
92 xmlDtd *doctype;
93 int ret;
94 size_t name_len = 0, publicid_len = 0, systemid_len = 0;
95 char *name = NULL, *publicid = NULL, *systemid = NULL;
96 xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL;
97 xmlURIPtr uri;
98
99 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sss", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) == FAILURE) {
100 return;
101 }
102
103 if (name_len == 0) {
104 php_error_docref(NULL, E_WARNING, "qualifiedName is required");
105 RETURN_FALSE;
106 }
107
108 if (publicid_len > 0) {
109 pch1 = (xmlChar *) publicid;
110 }
111 if (systemid_len > 0) {
112 pch2 = (xmlChar *) systemid;
113 }
114
115 if (strstr(name, "%00")) {
116 php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
117 RETURN_FALSE;
118 }
119
120 uri = xmlParseURI(name);
121 if (uri != NULL && uri->opaque != NULL) {
122 localname = xmlStrdup((xmlChar *) uri->opaque);
123 if (xmlStrchr(localname, (xmlChar) ':') != NULL) {
124 php_dom_throw_error(NAMESPACE_ERR, 1);
125 xmlFreeURI(uri);
126 xmlFree(localname);
127 RETURN_FALSE;
128 }
129 } else {
130 localname = xmlStrdup((xmlChar *) name);
131 }
132
133 /* TODO: Test that localname has no invalid chars
134 php_dom_throw_error(INVALID_CHARACTER_ERR,);
135 */
136
137 if (uri) {
138 xmlFreeURI(uri);
139 }
140
141 doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2);
142 xmlFree(localname);
143
144 if (doctype == NULL) {
145 php_error_docref(NULL, E_WARNING, "Unable to create DocumentType");
146 RETURN_FALSE;
147 }
148
149 DOM_RET_OBJ((xmlNodePtr) doctype, &ret, NULL);
150 }
151 /* }}} end dom_domimplementation_create_document_type */
152
153 /* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);
154 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
155 Since: DOM Level 2
156 */
PHP_METHOD(domimplementation,createDocument)157 PHP_METHOD(domimplementation, createDocument)
158 {
159 zval *node = NULL;
160 xmlDoc *docp;
161 xmlNode *nodep;
162 xmlDtdPtr doctype = NULL;
163 xmlNsPtr nsptr = NULL;
164 int ret, errorcode = 0;
165 size_t uri_len = 0, name_len = 0;
166 char *uri = NULL, *name = NULL;
167 char *prefix = NULL, *localname = NULL;
168 dom_object *doctobj;
169
170 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) {
171 return;
172 }
173
174 if (node != NULL) {
175 DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj);
176 if (doctype->type == XML_DOCUMENT_TYPE_NODE) {
177 php_error_docref(NULL, E_WARNING, "Invalid DocumentType object");
178 RETURN_FALSE;
179 }
180 if (doctype->doc != NULL) {
181 php_dom_throw_error(WRONG_DOCUMENT_ERR, 1);
182 RETURN_FALSE;
183 }
184 } else {
185 doctobj = NULL;
186 }
187
188 if (name_len > 0) {
189 errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len);
190 if (errorcode == 0 && uri_len > 0
191 && ((nsptr = xmlNewNs(NULL, (xmlChar *) uri, (xmlChar *) prefix)) == NULL)
192 ) {
193 errorcode = NAMESPACE_ERR;
194 }
195 }
196
197 if (prefix != NULL) {
198 xmlFree(prefix);
199 }
200
201 if (errorcode != 0) {
202 if (localname != NULL) {
203 xmlFree(localname);
204 }
205 php_dom_throw_error(errorcode, 1);
206 RETURN_FALSE;
207 }
208
209 /* currently letting libxml2 set the version string */
210 docp = xmlNewDoc(NULL);
211 if (!docp) {
212 if (localname != NULL) {
213 xmlFree(localname);
214 }
215 RETURN_FALSE;
216 }
217
218 if (doctype != NULL) {
219 docp->intSubset = doctype;
220 doctype->parent = docp;
221 doctype->doc = docp;
222 docp->children = (xmlNodePtr) doctype;
223 docp->last = (xmlNodePtr) doctype;
224 }
225
226 if (localname != NULL) {
227 nodep = xmlNewDocNode(docp, nsptr, (xmlChar *) localname, NULL);
228 if (!nodep) {
229 if (doctype != NULL) {
230 docp->intSubset = NULL;
231 doctype->parent = NULL;
232 doctype->doc = NULL;
233 docp->children = NULL;
234 docp->last = NULL;
235 }
236 xmlFreeDoc(docp);
237 xmlFree(localname);
238 /* Need some type of error here */
239 php_error_docref(NULL, E_WARNING, "Unexpected Error");
240 RETURN_FALSE;
241 }
242
243 nodep->nsDef = nsptr;
244
245 xmlDocSetRootElement(docp, nodep);
246 xmlFree(localname);
247 }
248
249 DOM_RET_OBJ((xmlNodePtr) docp, &ret, NULL);
250
251 if (doctobj != NULL) {
252 doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
253 php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp);
254 }
255 }
256 /* }}} end dom_domimplementation_create_document */
257
258 /* {{{ proto DOMNode dom_domimplementation_get_feature(string feature, string version);
259 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature
260 Since: DOM Level 3
261 */
PHP_METHOD(domimplementation,getFeature)262 PHP_METHOD(domimplementation, getFeature)
263 {
264 DOM_NOT_IMPLEMENTED();
265 }
266 /* }}} end dom_domimplementation_get_feature */
267
268 #endif
269
270 /*
271 * Local variables:
272 * tab-width: 4
273 * c-basic-offset: 4
274 * End:
275 * vim600: noet sw=4 ts=4 fdm=marker
276 * vim<600: noet sw=4 ts=4
277 */
278