1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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 : | Author: John Coggeshall <john@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: tidy.c 272922 2009-01-06 23:45:16Z iliaa $ */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include "config.h"
23 : #endif
24 :
25 : #include "php.h"
26 : #include "php_tidy.h"
27 :
28 : #if HAVE_TIDY
29 :
30 : #include "php_ini.h"
31 : #include "ext/standard/info.h"
32 : #include "safe_mode.h"
33 :
34 : #include "tidy.h"
35 : #include "buffio.h"
36 :
37 : /* compatibility with older versions of libtidy */
38 : #ifndef TIDY_CALL
39 : #define TIDY_CALL
40 : #endif
41 :
42 : #define PHP_TIDY_MODULE_VERSION "2.0"
43 :
44 : /* {{{ ext/tidy macros
45 : */
46 : #define TIDY_SET_CONTEXT \
47 : zval *object = getThis();
48 :
49 : #define TIDY_FETCH_OBJECT \
50 : PHPTidyObj *obj; \
51 : TIDY_SET_CONTEXT; \
52 : if (object) { \
53 : if (zend_parse_parameters_none() == FAILURE) { \
54 : return; \
55 : } \
56 : } else { \
57 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { \
58 : RETURN_FALSE; \
59 : } \
60 : } \
61 : obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); \
62 :
63 : #define TIDY_FETCH_ONLY_OBJECT \
64 : PHPTidyObj *obj; \
65 : TIDY_SET_CONTEXT; \
66 : if (zend_parse_parameters_none() == FAILURE) { \
67 : return; \
68 : } \
69 : obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); \
70 :
71 : #define TIDY_APPLY_CONFIG_ZVAL(_doc, _val) \
72 : if(_val) { \
73 : if(Z_TYPE_PP(_val) == IS_ARRAY) { \
74 : _php_tidy_apply_config_array(_doc, HASH_OF(*_val) TSRMLS_CC); \
75 : } else { \
76 : convert_to_string_ex(_val); \
77 : TIDY_SAFE_MODE_CHECK(Z_STRVAL_PP(_val)); \
78 : switch (tidyLoadConfig(_doc, Z_STRVAL_PP(_val))) { \
79 : case -1: \
80 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_PP(_val)); \
81 : break; \
82 : case 1: \
83 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_PP(_val)); \
84 : break; \
85 : } \
86 : } \
87 : }
88 :
89 : #define REGISTER_TIDY_CLASS(classname, name, parent, __flags) \
90 : { \
91 : zend_class_entry ce; \
92 : INIT_CLASS_ENTRY(ce, # classname, tidy_funcs_ ## name); \
93 : ce.create_object = tidy_object_new_ ## name; \
94 : tidy_ce_ ## name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
95 : tidy_ce_ ## name->ce_flags |= __flags; \
96 : memcpy(&tidy_object_handlers_ ## name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
97 : tidy_object_handlers_ ## name.clone_obj = NULL; \
98 : }
99 :
100 : #define TIDY_TAG_CONST(tag) REGISTER_LONG_CONSTANT("TIDY_TAG_" #tag, TidyTag_##tag, CONST_CS | CONST_PERSISTENT)
101 : #define TIDY_NODE_CONST(name, type) REGISTER_LONG_CONSTANT("TIDY_NODETYPE_" #name, TidyNode_##type, CONST_CS | CONST_PERSISTENT)
102 :
103 : #ifndef TRUE
104 : #define TRUE 1
105 : #endif
106 :
107 : #ifndef FALSE
108 : #define FALSE 0
109 : #endif
110 :
111 : #define ADD_PROPERTY_STRING(_table, _key, _string) \
112 : { \
113 : zval *tmp; \
114 : MAKE_STD_ZVAL(tmp); \
115 : if (_string) { \
116 : ZVAL_STRING(tmp, (char *)_string, 1); \
117 : } else { \
118 : ZVAL_EMPTY_STRING(tmp); \
119 : } \
120 : zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
121 : }
122 :
123 : #define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \
124 : { \
125 : zval *tmp; \
126 : MAKE_STD_ZVAL(tmp); \
127 : if (_string) { \
128 : ZVAL_STRINGL(tmp, (char *)_string, _len, 1); \
129 : } else { \
130 : ZVAL_EMPTY_STRING(tmp); \
131 : } \
132 : zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
133 : }
134 :
135 : #define ADD_PROPERTY_LONG(_table, _key, _long) \
136 : { \
137 : zval *tmp; \
138 : MAKE_STD_ZVAL(tmp); \
139 : ZVAL_LONG(tmp, _long); \
140 : zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
141 : }
142 :
143 : #define ADD_PROPERTY_NULL(_table, _key) \
144 : { \
145 : zval *tmp; \
146 : MAKE_STD_ZVAL(tmp); \
147 : ZVAL_NULL(tmp); \
148 : zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
149 : }
150 :
151 : #define ADD_PROPERTY_BOOL(_table, _key, _bool) \
152 : { \
153 : zval *tmp; \
154 : MAKE_STD_ZVAL(tmp); \
155 : ZVAL_BOOL(tmp, _bool); \
156 : zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
157 : }
158 :
159 : #define TIDY_SAFE_MODE_CHECK(filename) \
160 : if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) { \
161 : RETURN_FALSE; \
162 : } \
163 :
164 : #define TIDY_SET_DEFAULT_CONFIG(_doc) \
165 : if (TG(default_config) && TG(default_config)[0]) { \
166 : if (tidyLoadConfig(_doc, TG(default_config)) < 0) { \
167 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load Tidy configuration file at '%s'.", TG(default_config)); \
168 : } \
169 : }
170 : /* }}} */
171 :
172 : /* {{{ ext/tidy structs
173 : */
174 : typedef struct _PHPTidyDoc PHPTidyDoc;
175 : typedef struct _PHPTidyObj PHPTidyObj;
176 :
177 : typedef enum {
178 : is_node,
179 : is_doc
180 : } tidy_obj_type;
181 :
182 : typedef enum {
183 : is_root_node,
184 : is_html_node,
185 : is_head_node,
186 : is_body_node
187 : } tidy_base_nodetypes;
188 :
189 : struct _PHPTidyDoc {
190 : TidyDoc doc;
191 : TidyBuffer *errbuf;
192 : unsigned int ref_count;
193 : };
194 :
195 : struct _PHPTidyObj {
196 : zend_object std;
197 : TidyNode node;
198 : tidy_obj_type type;
199 : PHPTidyDoc *ptdoc;
200 : };
201 : /* }}} */
202 :
203 : /* {{{ ext/tidy prototypes
204 : */
205 : static char *php_tidy_file_to_mem(char *, zend_bool, int * TSRMLS_DC);
206 : static void tidy_object_free_storage(void * TSRMLS_DC);
207 : static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC);
208 : static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
209 : static zend_class_entry *tidy_get_ce_node(const zval * TSRMLS_DC);
210 : static zend_class_entry *tidy_get_ce_doc(const zval * TSRMLS_DC);
211 : static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC);
212 : static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC);
213 : static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC);
214 : static void tidy_doc_update_properties(PHPTidyObj * TSRMLS_DC);
215 : static void tidy_add_default_properties(PHPTidyObj *, tidy_obj_type TSRMLS_DC);
216 : static void *php_tidy_get_opt_val(PHPTidyDoc *, TidyOption, TidyOptionType * TSRMLS_DC);
217 : static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes);
218 : static int _php_tidy_set_tidy_opt(TidyDoc, char *, zval * TSRMLS_DC);
219 : static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC);
220 : static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS);
221 : static void _php_tidy_register_tags(INIT_FUNC_ARGS);
222 :
223 : static PHP_MINIT_FUNCTION(tidy);
224 : static PHP_MSHUTDOWN_FUNCTION(tidy);
225 : static PHP_RINIT_FUNCTION(tidy);
226 : static PHP_MINFO_FUNCTION(tidy);
227 :
228 : static PHP_FUNCTION(tidy_getopt);
229 : static PHP_FUNCTION(tidy_parse_string);
230 : static PHP_FUNCTION(tidy_parse_file);
231 : static PHP_FUNCTION(tidy_clean_repair);
232 : static PHP_FUNCTION(tidy_repair_string);
233 : static PHP_FUNCTION(tidy_repair_file);
234 : static PHP_FUNCTION(tidy_diagnose);
235 : static PHP_FUNCTION(tidy_get_output);
236 : static PHP_FUNCTION(tidy_get_error_buffer);
237 : static PHP_FUNCTION(tidy_get_release);
238 : static PHP_FUNCTION(tidy_get_config);
239 : static PHP_FUNCTION(tidy_get_status);
240 : static PHP_FUNCTION(tidy_get_html_ver);
241 : #if HAVE_TIDYOPTGETDOC
242 : static PHP_FUNCTION(tidy_get_opt_doc);
243 : #endif
244 : static PHP_FUNCTION(tidy_is_xhtml);
245 : static PHP_FUNCTION(tidy_is_xml);
246 : static PHP_FUNCTION(tidy_error_count);
247 : static PHP_FUNCTION(tidy_warning_count);
248 : static PHP_FUNCTION(tidy_access_count);
249 : static PHP_FUNCTION(tidy_config_count);
250 :
251 : static PHP_FUNCTION(ob_tidyhandler);
252 :
253 : static PHP_FUNCTION(tidy_get_root);
254 : static PHP_FUNCTION(tidy_get_html);
255 : static PHP_FUNCTION(tidy_get_head);
256 : static PHP_FUNCTION(tidy_get_body);
257 :
258 : static TIDY_DOC_METHOD(__construct);
259 : static TIDY_DOC_METHOD(parseFile);
260 : static TIDY_DOC_METHOD(parseString);
261 :
262 : static TIDY_NODE_METHOD(hasChildren);
263 : static TIDY_NODE_METHOD(hasSiblings);
264 : static TIDY_NODE_METHOD(isComment);
265 : static TIDY_NODE_METHOD(isHtml);
266 : static TIDY_NODE_METHOD(isText);
267 : static TIDY_NODE_METHOD(isJste);
268 : static TIDY_NODE_METHOD(isAsp);
269 : static TIDY_NODE_METHOD(isPhp);
270 : static TIDY_NODE_METHOD(getParent);
271 : /* }}} */
272 :
273 : ZEND_DECLARE_MODULE_GLOBALS(tidy)
274 :
275 : PHP_INI_BEGIN()
276 : STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals)
277 : PHP_INI_ENTRY("tidy.clean_output", "0", PHP_INI_PERDIR, NULL)
278 : PHP_INI_END()
279 :
280 : /* {{{ arginfo */
281 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_parse_string, 0, 0, 1)
282 : ZEND_ARG_INFO(0, input)
283 : ZEND_ARG_INFO(0, config_options)
284 : ZEND_ARG_INFO(0, encoding)
285 : ZEND_END_ARG_INFO()
286 :
287 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_error_buffer, 0, 0, 0)
288 : ZEND_ARG_INFO(0, detailed)
289 : ZEND_END_ARG_INFO()
290 :
291 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_output, 0)
292 : ZEND_END_ARG_INFO()
293 :
294 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_parse_file, 0, 0, 1)
295 : ZEND_ARG_INFO(0, file)
296 : ZEND_ARG_INFO(0, config_options)
297 : ZEND_ARG_INFO(0, encoding)
298 : ZEND_ARG_INFO(0, use_include_path)
299 : ZEND_END_ARG_INFO()
300 :
301 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_clean_repair, 0)
302 : ZEND_END_ARG_INFO()
303 :
304 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_repair_string, 0, 0, 1)
305 : ZEND_ARG_INFO(0, data)
306 : ZEND_ARG_INFO(0, config_file)
307 : ZEND_ARG_INFO(0, encoding)
308 : ZEND_END_ARG_INFO()
309 :
310 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_repair_file, 0, 0, 1)
311 : ZEND_ARG_INFO(0, filename)
312 : ZEND_ARG_INFO(0, config_file)
313 : ZEND_ARG_INFO(0, encoding)
314 : ZEND_ARG_INFO(0, use_include_path)
315 : ZEND_END_ARG_INFO()
316 :
317 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_diagnose, 0)
318 : ZEND_END_ARG_INFO()
319 :
320 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_release, 0)
321 : ZEND_END_ARG_INFO()
322 :
323 : #if HAVE_TIDYOPTGETDOC
324 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_opt_doc, 0, 0, 2)
325 : ZEND_ARG_INFO(0, resource)
326 : ZEND_ARG_INFO(0, optname)
327 : ZEND_END_ARG_INFO()
328 : #endif
329 :
330 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_config, 0)
331 : ZEND_END_ARG_INFO()
332 :
333 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_status, 0)
334 : ZEND_END_ARG_INFO()
335 :
336 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_html_ver, 0)
337 : ZEND_END_ARG_INFO()
338 :
339 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_is_xhtml, 0)
340 : ZEND_END_ARG_INFO()
341 :
342 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_is_xml, 0)
343 : ZEND_END_ARG_INFO()
344 :
345 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_error_count, 0)
346 : ZEND_END_ARG_INFO()
347 :
348 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_warning_count, 0)
349 : ZEND_END_ARG_INFO()
350 :
351 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_access_count, 0)
352 : ZEND_END_ARG_INFO()
353 :
354 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_config_count, 0)
355 : ZEND_END_ARG_INFO()
356 :
357 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_getopt, 0, 0, 1)
358 : ZEND_ARG_INFO(0, option)
359 : ZEND_END_ARG_INFO()
360 :
361 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_root, 0)
362 : ZEND_END_ARG_INFO()
363 :
364 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_html, 0)
365 : ZEND_END_ARG_INFO()
366 :
367 : ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_head, 0)
368 : ZEND_END_ARG_INFO()
369 :
370 : ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_body, 0, 0, 1)
371 : ZEND_ARG_INFO(0, tidy)
372 : ZEND_END_ARG_INFO()
373 :
374 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_tidyhandler, 0, 0, 1)
375 : ZEND_ARG_INFO(0, input)
376 : ZEND_ARG_INFO(0, mode)
377 : ZEND_END_ARG_INFO()
378 : /* }}} */
379 :
380 : static const zend_function_entry tidy_functions[] = {
381 : PHP_FE(tidy_getopt, arginfo_tidy_getopt)
382 : PHP_FE(tidy_parse_string, arginfo_tidy_parse_string)
383 : PHP_FE(tidy_parse_file, arginfo_tidy_parse_file)
384 : PHP_FE(tidy_get_output, arginfo_tidy_get_output)
385 : PHP_FE(tidy_get_error_buffer, arginfo_tidy_get_error_buffer)
386 : PHP_FE(tidy_clean_repair, arginfo_tidy_clean_repair)
387 : PHP_FE(tidy_repair_string, arginfo_tidy_repair_string)
388 : PHP_FE(tidy_repair_file, arginfo_tidy_repair_file)
389 : PHP_FE(tidy_diagnose, arginfo_tidy_diagnose)
390 : PHP_FE(tidy_get_release, arginfo_tidy_get_release)
391 : PHP_FE(tidy_get_config, arginfo_tidy_get_config)
392 : PHP_FE(tidy_get_status, arginfo_tidy_get_status)
393 : PHP_FE(tidy_get_html_ver, arginfo_tidy_get_html_ver)
394 : PHP_FE(tidy_is_xhtml, arginfo_tidy_is_xhtml)
395 : PHP_FE(tidy_is_xml, arginfo_tidy_is_xml)
396 : PHP_FE(tidy_error_count, arginfo_tidy_error_count)
397 : PHP_FE(tidy_warning_count, arginfo_tidy_warning_count)
398 : PHP_FE(tidy_access_count, arginfo_tidy_access_count)
399 : PHP_FE(tidy_config_count, arginfo_tidy_config_count)
400 : #if HAVE_TIDYOPTGETDOC
401 : PHP_FE(tidy_get_opt_doc, arginfo_tidy_get_opt_doc)
402 : #endif
403 : PHP_FE(tidy_get_root, arginfo_tidy_get_root)
404 : PHP_FE(tidy_get_head, arginfo_tidy_get_head)
405 : PHP_FE(tidy_get_html, arginfo_tidy_get_html)
406 : PHP_FE(tidy_get_body, arginfo_tidy_get_body)
407 : PHP_FE(ob_tidyhandler, arginfo_ob_tidyhandler)
408 : {NULL, NULL, NULL}
409 : };
410 :
411 : static const zend_function_entry tidy_funcs_doc[] = {
412 : TIDY_METHOD_MAP(getOpt, tidy_getopt, NULL)
413 : TIDY_METHOD_MAP(cleanRepair, tidy_clean_repair, NULL)
414 : TIDY_DOC_ME(parseFile, NULL)
415 : TIDY_DOC_ME(parseString, NULL)
416 : TIDY_METHOD_MAP(repairString, tidy_repair_string, NULL)
417 : TIDY_METHOD_MAP(repairFile, tidy_repair_file, NULL)
418 : TIDY_METHOD_MAP(diagnose, tidy_diagnose, NULL)
419 : TIDY_METHOD_MAP(getRelease, tidy_get_release, NULL)
420 : TIDY_METHOD_MAP(getConfig, tidy_get_config, NULL)
421 : TIDY_METHOD_MAP(getStatus, tidy_get_status, NULL)
422 : TIDY_METHOD_MAP(getHtmlVer, tidy_get_html_ver, NULL)
423 : #if HAVE_TIDYOPTGETDOC
424 : TIDY_METHOD_MAP(getOptDoc, tidy_get_opt_doc, NULL)
425 : #endif
426 : TIDY_METHOD_MAP(isXhtml, tidy_is_xhtml, NULL)
427 : TIDY_METHOD_MAP(isXml, tidy_is_xml, NULL)
428 : TIDY_METHOD_MAP(root, tidy_get_root, NULL)
429 : TIDY_METHOD_MAP(head, tidy_get_head, NULL)
430 : TIDY_METHOD_MAP(html, tidy_get_html, NULL)
431 : TIDY_METHOD_MAP(body, tidy_get_body, NULL)
432 : TIDY_DOC_ME(__construct, NULL)
433 : {NULL, NULL, NULL}
434 : };
435 :
436 : static const zend_function_entry tidy_funcs_node[] = {
437 : TIDY_NODE_ME(hasChildren, NULL)
438 : TIDY_NODE_ME(hasSiblings, NULL)
439 : TIDY_NODE_ME(isComment, NULL)
440 : TIDY_NODE_ME(isHtml, NULL)
441 : TIDY_NODE_ME(isText, NULL)
442 : TIDY_NODE_ME(isJste, NULL)
443 : TIDY_NODE_ME(isAsp, NULL)
444 : TIDY_NODE_ME(isPhp, NULL)
445 : TIDY_NODE_ME(getParent, NULL)
446 : {NULL, NULL, NULL}
447 : };
448 :
449 : static zend_class_entry *tidy_ce_doc, *tidy_ce_node;
450 :
451 : static zend_object_handlers tidy_object_handlers_doc;
452 : static zend_object_handlers tidy_object_handlers_node;
453 :
454 : zend_module_entry tidy_module_entry = {
455 : STANDARD_MODULE_HEADER,
456 : "tidy",
457 : tidy_functions,
458 : PHP_MINIT(tidy),
459 : PHP_MSHUTDOWN(tidy),
460 : PHP_RINIT(tidy),
461 : NULL,
462 : PHP_MINFO(tidy),
463 : PHP_TIDY_MODULE_VERSION,
464 : PHP_MODULE_GLOBALS(tidy),
465 : NULL,
466 : NULL,
467 : NULL,
468 : STANDARD_MODULE_PROPERTIES_EX
469 : };
470 :
471 : #ifdef COMPILE_DL_TIDY
472 : ZEND_GET_MODULE(tidy)
473 : #endif
474 :
475 : static void* TIDY_CALL php_tidy_malloc(size_t len)
476 1655 : {
477 1655 : return emalloc(len);
478 : }
479 :
480 : static void* TIDY_CALL php_tidy_realloc(void *buf, size_t len)
481 13 : {
482 13 : return erealloc(buf, len);
483 : }
484 :
485 : static void TIDY_CALL php_tidy_free(void *buf)
486 1655 : {
487 1655 : efree(buf);
488 1655 : }
489 :
490 : static void TIDY_CALL php_tidy_panic(ctmbstr msg)
491 0 : {
492 : TSRMLS_FETCH();
493 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not allocate memory for tidy! (Reason: %s)", (char *)msg);
494 0 : }
495 :
496 : static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS_DC)
497 23 : {
498 23 : TidyOption opt = tidyGetOptionByName(doc, optname);
499 23 : zval conv = *value;
500 :
501 23 : if (!opt) {
502 1 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown Tidy Configuration Option '%s'", optname);
503 1 : return FAILURE;
504 : }
505 :
506 22 : if (tidyOptIsReadOnly(opt)) {
507 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Attempting to set read-only option '%s'", optname);
508 0 : return FAILURE;
509 : }
510 :
511 22 : switch(tidyOptGetType(opt)) {
512 : case TidyString:
513 3 : if (Z_TYPE(conv) != IS_STRING) {
514 0 : zval_copy_ctor(&conv);
515 0 : convert_to_string(&conv);
516 : }
517 3 : if (tidyOptSetValue(doc, tidyOptGetId(opt), Z_STRVAL(conv))) {
518 2 : if (Z_TYPE(conv) != Z_TYPE_P(value)) {
519 0 : zval_dtor(&conv);
520 : }
521 2 : return SUCCESS;
522 : }
523 1 : if (Z_TYPE(conv) != Z_TYPE_P(value)) {
524 0 : zval_dtor(&conv);
525 : }
526 1 : break;
527 :
528 : case TidyInteger:
529 11 : if (Z_TYPE(conv) != IS_LONG) {
530 8 : zval_copy_ctor(&conv);
531 8 : convert_to_long(&conv);
532 : }
533 11 : if (tidyOptSetInt(doc, tidyOptGetId(opt), Z_LVAL(conv))) {
534 11 : return SUCCESS;
535 : }
536 0 : break;
537 :
538 : case TidyBoolean:
539 8 : if (Z_TYPE(conv) != IS_LONG) {
540 7 : zval_copy_ctor(&conv);
541 7 : convert_to_long(&conv);
542 : }
543 8 : if (tidyOptSetBool(doc, tidyOptGetId(opt), Z_LVAL(conv))) {
544 8 : return SUCCESS;
545 : }
546 0 : break;
547 :
548 : default:
549 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of configuration option");
550 : break;
551 : }
552 :
553 1 : return FAILURE;
554 : }
555 :
556 : static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file)
557 17 : {
558 17 : char *data=NULL, *arg1, *enc = NULL;
559 17 : int arg1_len, enc_len = 0, data_len = 0;
560 17 : zend_bool use_include_path = 0;
561 : TidyDoc doc;
562 : TidyBuffer *errbuf;
563 17 : zval **config = NULL;
564 :
565 17 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
566 4 : RETURN_FALSE;
567 : }
568 :
569 13 : if (is_file) {
570 6 : if (!(data = php_tidy_file_to_mem(arg1, use_include_path, &data_len TSRMLS_CC))) {
571 6 : RETURN_FALSE;
572 : }
573 : } else {
574 7 : data = arg1;
575 7 : data_len = arg1_len;
576 : }
577 :
578 7 : doc = tidyCreate();
579 7 : errbuf = emalloc(sizeof(TidyBuffer));
580 7 : tidyBufInit(errbuf);
581 :
582 7 : if (tidySetErrorBuffer(doc, errbuf) != 0) {
583 0 : tidyBufFree(errbuf);
584 0 : efree(errbuf);
585 0 : tidyRelease(doc);
586 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
587 : }
588 :
589 7 : tidyOptSetBool(doc, TidyForceOutput, yes);
590 7 : tidyOptSetBool(doc, TidyMark, no);
591 :
592 7 : TIDY_SET_DEFAULT_CONFIG(doc);
593 :
594 7 : if (config) {
595 7 : TIDY_APPLY_CONFIG_ZVAL(doc, config);
596 : }
597 :
598 7 : if(enc_len) {
599 4 : if (tidySetCharEncoding(doc, enc) < 0) {
600 4 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
601 4 : RETVAL_FALSE;
602 : }
603 : }
604 :
605 7 : if (data) {
606 : TidyBuffer buf;
607 :
608 7 : tidyBufInit(&buf);
609 7 : tidyBufAppend(&buf, data, data_len);
610 :
611 7 : if (tidyParseBuffer(doc, &buf) < 0) {
612 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
613 0 : RETVAL_FALSE;
614 : } else {
615 7 : if (tidyCleanAndRepair(doc) >= 0) {
616 : TidyBuffer output;
617 7 : tidyBufInit(&output);
618 :
619 7 : tidySaveBuffer (doc, &output);
620 7 : RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
621 7 : tidyBufFree(&output);
622 : } else {
623 0 : RETVAL_FALSE;
624 : }
625 : }
626 :
627 7 : tidyBufFree(&buf);
628 : }
629 :
630 7 : if (is_file) {
631 0 : efree(data);
632 : }
633 :
634 7 : tidyBufFree(errbuf);
635 7 : efree(errbuf);
636 7 : tidyRelease(doc);
637 : }
638 :
639 : static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, int *len TSRMLS_DC)
640 11 : {
641 : php_stream *stream;
642 11 : char *data = NULL;
643 :
644 11 : if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE, NULL))) {
645 6 : return NULL;
646 : }
647 5 : if ((*len = (int) php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
648 0 : data = estrdup("");
649 0 : *len = 0;
650 : }
651 5 : php_stream_close(stream);
652 :
653 5 : return data;
654 : }
655 :
656 : static void tidy_object_free_storage(void *object TSRMLS_DC)
657 155 : {
658 155 : PHPTidyObj *intern = (PHPTidyObj *)object;
659 :
660 155 : zend_object_std_dtor(&intern->std TSRMLS_CC);
661 :
662 155 : if (intern->ptdoc) {
663 150 : intern->ptdoc->ref_count--;
664 :
665 150 : if (intern->ptdoc->ref_count <= 0) {
666 39 : tidyBufFree(intern->ptdoc->errbuf);
667 39 : efree(intern->ptdoc->errbuf);
668 39 : tidyRelease(intern->ptdoc->doc);
669 39 : efree(intern->ptdoc);
670 : }
671 : }
672 :
673 155 : efree(object);
674 155 : }
675 :
676 : static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers,
677 : zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC)
678 155 : {
679 : PHPTidyObj *intern;
680 : zval *tmp;
681 :
682 155 : intern = emalloc(sizeof(PHPTidyObj));
683 155 : memset(intern, 0, sizeof(PHPTidyObj));
684 155 : zend_object_std_init(&intern->std, class_type TSRMLS_CC);
685 :
686 155 : zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
687 :
688 155 : switch(objtype) {
689 : case is_node:
690 116 : break;
691 :
692 : case is_doc:
693 39 : tidySetMallocCall(php_tidy_malloc);
694 39 : tidySetReallocCall(php_tidy_realloc);
695 39 : tidySetFreeCall(php_tidy_free);
696 39 : tidySetPanicCall(php_tidy_panic);
697 :
698 39 : intern->ptdoc = emalloc(sizeof(PHPTidyDoc));
699 39 : intern->ptdoc->doc = tidyCreate();
700 39 : intern->ptdoc->ref_count = 1;
701 39 : intern->ptdoc->errbuf = emalloc(sizeof(TidyBuffer));
702 39 : tidyBufInit(intern->ptdoc->errbuf);
703 :
704 39 : if (tidySetErrorBuffer(intern->ptdoc->doc, intern->ptdoc->errbuf) != 0) {
705 0 : tidyBufFree(intern->ptdoc->errbuf);
706 0 : efree(intern->ptdoc->errbuf);
707 0 : tidyRelease(intern->ptdoc->doc);
708 0 : efree(intern->ptdoc);
709 0 : efree(intern);
710 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
711 : }
712 :
713 39 : tidyOptSetBool(intern->ptdoc->doc, TidyForceOutput, yes);
714 39 : tidyOptSetBool(intern->ptdoc->doc, TidyMark, no);
715 :
716 39 : TIDY_SET_DEFAULT_CONFIG(intern->ptdoc->doc);
717 :
718 39 : tidy_add_default_properties(intern, is_doc TSRMLS_CC);
719 : break;
720 :
721 : default:
722 : break;
723 : }
724 :
725 155 : retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) tidy_object_free_storage, NULL TSRMLS_CC);
726 155 : retval->handlers = handlers;
727 155 : }
728 :
729 : static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC)
730 116 : {
731 : zend_object_value retval;
732 116 : tidy_object_new(class_type, &tidy_object_handlers_node, &retval, is_node TSRMLS_CC);
733 116 : return retval;
734 : }
735 :
736 : static zend_object_value tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC)
737 39 : {
738 : zend_object_value retval;
739 39 : tidy_object_new(class_type, &tidy_object_handlers_doc, &retval, is_doc TSRMLS_CC);
740 39 : return retval;
741 : }
742 :
743 : static zend_class_entry *tidy_get_ce_node(const zval *object TSRMLS_DC)
744 45 : {
745 45 : return tidy_ce_node;
746 : }
747 :
748 : static zend_class_entry *tidy_get_ce_doc(const zval *object TSRMLS_DC)
749 69 : {
750 69 : return tidy_ce_doc;
751 : }
752 :
753 : static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
754 139 : {
755 139 : if (!object) {
756 0 : ALLOC_ZVAL(object);
757 : }
758 :
759 139 : Z_TYPE_P(object) = IS_OBJECT;
760 139 : object_init_ex(object, pce);
761 139 : Z_SET_REFCOUNT_P(object, 1);
762 139 : Z_SET_ISREF_P(object);
763 139 : return object;
764 : }
765 :
766 : static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
767 4 : {
768 : TidyBuffer output;
769 : PHPTidyObj *obj;
770 :
771 4 : switch(type) {
772 : case IS_LONG:
773 0 : ZVAL_LONG(out, 0);
774 0 : break;
775 :
776 : case IS_DOUBLE:
777 0 : ZVAL_DOUBLE(out, 0);
778 0 : break;
779 :
780 : case IS_BOOL:
781 0 : ZVAL_BOOL(out, TRUE);
782 0 : break;
783 :
784 : case IS_STRING:
785 4 : obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
786 4 : tidyBufInit(&output);
787 4 : tidySaveBuffer (obj->ptdoc->doc, &output);
788 4 : ZVAL_STRINGL(out, (char*)output.bp, output.size ? output.size-1 : 0, TRUE);
789 4 : tidyBufFree(&output);
790 4 : break;
791 :
792 : default:
793 0 : return FAILURE;
794 : }
795 :
796 4 : return SUCCESS;
797 : }
798 :
799 : static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
800 5 : {
801 : TidyBuffer buf;
802 : PHPTidyObj *obj;
803 :
804 5 : switch(type) {
805 : case IS_LONG:
806 1 : ZVAL_LONG(out, 0);
807 1 : break;
808 :
809 : case IS_DOUBLE:
810 1 : ZVAL_DOUBLE(out, 0);
811 1 : break;
812 :
813 : case IS_BOOL:
814 1 : ZVAL_BOOL(out, TRUE);
815 1 : break;
816 :
817 : case IS_STRING:
818 2 : obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
819 2 : tidyBufInit(&buf);
820 2 : if (obj->ptdoc) {
821 1 : tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
822 : }
823 2 : ZVAL_STRINGL(out, (char*)buf.bp, buf.size ? buf.size-1 : 0, TRUE);
824 2 : tidyBufFree(&buf);
825 2 : break;
826 :
827 : default:
828 0 : return FAILURE;
829 : }
830 :
831 5 : return SUCCESS;
832 : }
833 :
834 : static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
835 48 : {
836 :
837 : TidyBuffer output;
838 : zval *temp;
839 :
840 48 : tidyBufInit(&output);
841 48 : tidySaveBuffer (obj->ptdoc->doc, &output);
842 :
843 48 : if (output.size) {
844 46 : MAKE_STD_ZVAL(temp);
845 46 : ZVAL_STRINGL(temp, (char*)output.bp, output.size-1, TRUE);
846 46 : zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL);
847 : }
848 :
849 48 : tidyBufFree(&output);
850 :
851 48 : if (obj->ptdoc->errbuf->size) {
852 47 : MAKE_STD_ZVAL(temp);
853 47 : ZVAL_STRINGL(temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, TRUE);
854 47 : zend_hash_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer"), (void *)&temp, sizeof(zval *), NULL);
855 : }
856 48 : }
857 :
858 : static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRMLS_DC)
859 150 : {
860 :
861 : TidyBuffer buf;
862 : TidyAttr tempattr;
863 : TidyNode tempnode;
864 : zval *attribute, *children, *temp;
865 : PHPTidyObj *newobj;
866 :
867 150 : switch(type) {
868 :
869 : case is_node:
870 111 : tidyBufInit(&buf);
871 111 : tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
872 111 : ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size-1);
873 111 : tidyBufFree(&buf);
874 :
875 111 : ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node));
876 111 : ADD_PROPERTY_LONG(obj->std.properties, type, tidyNodeGetType(obj->node));
877 111 : ADD_PROPERTY_LONG(obj->std.properties, line, tidyNodeLine(obj->node));
878 111 : ADD_PROPERTY_LONG(obj->std.properties, column, tidyNodeColumn(obj->node));
879 111 : ADD_PROPERTY_BOOL(obj->std.properties, proprietary, tidyNodeIsProp(obj->ptdoc->doc, obj->node));
880 :
881 111 : switch(tidyNodeGetType(obj->node)) {
882 : case TidyNode_Root:
883 : case TidyNode_DocType:
884 : case TidyNode_Text:
885 : case TidyNode_Comment:
886 24 : break;
887 :
888 : default:
889 87 : ADD_PROPERTY_LONG(obj->std.properties, id, tidyNodeGetId(obj->node));
890 : }
891 :
892 111 : tempattr = tidyAttrFirst(obj->node);
893 111 : MAKE_STD_ZVAL(attribute);
894 :
895 111 : if (tempattr) {
896 : char *name, *val;
897 5 : array_init(attribute);
898 :
899 : do {
900 10 : name = (char *)tidyAttrName(tempattr);
901 10 : val = (char *)tidyAttrValue(tempattr);
902 10 : if (name && val) {
903 10 : add_assoc_string(attribute, name, val, TRUE);
904 : }
905 10 : } while((tempattr = tidyAttrNext(tempattr)));
906 : } else {
907 106 : ZVAL_NULL(attribute);
908 : }
909 111 : zend_hash_update(obj->std.properties, "attribute", sizeof("attribute"), (void *)&attribute, sizeof(zval *), NULL);
910 :
911 111 : tempnode = tidyGetChild(obj->node);
912 :
913 111 : MAKE_STD_ZVAL(children);
914 111 : if (tempnode) {
915 62 : array_init(children);
916 : do {
917 89 : MAKE_STD_ZVAL(temp);
918 89 : tidy_instanciate(tidy_ce_node, temp TSRMLS_CC);
919 89 : newobj = (PHPTidyObj *) zend_object_store_get_object(temp TSRMLS_CC);
920 89 : newobj->node = tempnode;
921 89 : newobj->type = is_node;
922 89 : newobj->ptdoc = obj->ptdoc;
923 89 : newobj->ptdoc->ref_count++;
924 :
925 89 : tidy_add_default_properties(newobj, is_node TSRMLS_CC);
926 89 : add_next_index_zval(children, temp);
927 :
928 89 : } while((tempnode = tidyGetNext(tempnode)));
929 :
930 : } else {
931 49 : ZVAL_NULL(children);
932 : }
933 :
934 111 : zend_hash_update(obj->std.properties, "child", sizeof("child"), (void *)&children, sizeof(zval *), NULL);
935 :
936 111 : break;
937 :
938 : case is_doc:
939 39 : ADD_PROPERTY_NULL(obj->std.properties, errorBuffer);
940 39 : ADD_PROPERTY_NULL(obj->std.properties, value);
941 : break;
942 : }
943 150 : }
944 :
945 : static void *php_tidy_get_opt_val(PHPTidyDoc *ptdoc, TidyOption opt, TidyOptionType *type TSRMLS_DC)
946 90 : {
947 90 : *type = tidyOptGetType(opt);
948 :
949 90 : switch (*type) {
950 : case TidyString: {
951 13 : char *val = (char *) tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt));
952 13 : if (val) {
953 1 : return (void *) estrdup(val);
954 : } else {
955 12 : return (void *) estrdup("");
956 : }
957 : }
958 : break;
959 :
960 : case TidyInteger:
961 18 : return (void *) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt));
962 : break;
963 :
964 : case TidyBoolean:
965 59 : return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt));
966 : break;
967 : }
968 :
969 : /* should not happen */
970 0 : return NULL;
971 : }
972 :
973 : static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes node_type)
974 23 : {
975 : PHPTidyObj *newobj;
976 : TidyNode node;
977 23 : TIDY_FETCH_OBJECT;
978 :
979 23 : switch (node_type) {
980 : case is_root_node:
981 14 : node = tidyGetRoot(obj->ptdoc->doc);
982 14 : break;
983 :
984 : case is_html_node:
985 2 : node = tidyGetHtml(obj->ptdoc->doc);
986 2 : break;
987 :
988 : case is_head_node:
989 1 : node = tidyGetHead(obj->ptdoc->doc);
990 1 : break;
991 :
992 : case is_body_node:
993 6 : node = tidyGetBody(obj->ptdoc->doc);
994 : break;
995 : }
996 :
997 23 : if (!node) {
998 2 : RETURN_NULL();
999 : }
1000 :
1001 21 : tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
1002 21 : newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
1003 21 : newobj->type = is_node;
1004 21 : newobj->ptdoc = obj->ptdoc;
1005 21 : newobj->node = node;
1006 21 : newobj->ptdoc->ref_count++;
1007 :
1008 21 : tidy_add_default_properties(newobj, is_node TSRMLS_CC);
1009 : }
1010 :
1011 : static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
1012 11 : {
1013 11 : char *opt_name = NULL;
1014 : zval **opt_val;
1015 : ulong opt_indx;
1016 :
1017 11 : for (zend_hash_internal_pointer_reset(ht_options);
1018 45 : zend_hash_get_current_data(ht_options, (void **)&opt_val) == SUCCESS;
1019 23 : zend_hash_move_forward(ht_options)) {
1020 :
1021 23 : if(zend_hash_get_current_key(ht_options, &opt_name, &opt_indx, FALSE) == FAILURE) {
1022 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
1023 0 : return FAILURE;
1024 : }
1025 :
1026 23 : if(opt_name) {
1027 23 : _php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC);
1028 23 : opt_name = NULL;
1029 : }
1030 :
1031 : }
1032 :
1033 11 : return SUCCESS;
1034 : }
1035 :
1036 : static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *enc TSRMLS_DC)
1037 35 : {
1038 : TidyBuffer buf;
1039 :
1040 35 : if(enc) {
1041 3 : if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) {
1042 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
1043 0 : return FAILURE;
1044 : }
1045 : }
1046 :
1047 35 : tidyBufInit(&buf);
1048 35 : tidyBufAppend(&buf, string, len);
1049 35 : if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) {
1050 0 : tidyBufFree(&buf);
1051 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", obj->ptdoc->errbuf->bp);
1052 0 : return FAILURE;
1053 :
1054 : }
1055 35 : tidyBufFree(&buf);
1056 35 : tidy_doc_update_properties(obj TSRMLS_CC);
1057 :
1058 35 : return SUCCESS;
1059 : }
1060 :
1061 : static PHP_MINIT_FUNCTION(tidy)
1062 17633 : {
1063 17633 : REGISTER_INI_ENTRIES();
1064 17633 : REGISTER_TIDY_CLASS(tidy, doc, NULL, 0);
1065 17633 : REGISTER_TIDY_CLASS(tidyNode, node, NULL, ZEND_ACC_FINAL_CLASS);
1066 :
1067 17633 : tidy_object_handlers_doc.get_class_entry = tidy_get_ce_doc;
1068 17633 : tidy_object_handlers_node.get_class_entry = tidy_get_ce_node;
1069 :
1070 17633 : tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler;
1071 17633 : tidy_object_handlers_node.cast_object = tidy_node_cast_handler;
1072 :
1073 17633 : _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU);
1074 17633 : _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU);
1075 :
1076 17633 : return SUCCESS;
1077 : }
1078 :
1079 : static PHP_RINIT_FUNCTION(tidy)
1080 17619 : {
1081 17619 : if (INI_BOOL("tidy.clean_output") == TRUE) {
1082 2 : if (php_start_ob_buffer_named("ob_tidyhandler", 0, 1 TSRMLS_CC) == FAILURE) {
1083 0 : zend_error(E_NOTICE, "Failure installing Tidy output buffering.");
1084 : }
1085 : }
1086 :
1087 17619 : return SUCCESS;
1088 : }
1089 :
1090 : static PHP_MSHUTDOWN_FUNCTION(tidy)
1091 17665 : {
1092 17665 : UNREGISTER_INI_ENTRIES();
1093 17665 : return SUCCESS;
1094 : }
1095 :
1096 : static PHP_MINFO_FUNCTION(tidy)
1097 42 : {
1098 42 : php_info_print_table_start();
1099 42 : php_info_print_table_header(2, "Tidy support", "enabled");
1100 42 : php_info_print_table_row(2, "libTidy Release", (char *)tidyReleaseDate());
1101 42 : php_info_print_table_row(2, "Extension Version", PHP_TIDY_MODULE_VERSION " ($Id: tidy.c 272922 2009-01-06 23:45:16Z iliaa $)");
1102 42 : php_info_print_table_end();
1103 :
1104 42 : DISPLAY_INI_ENTRIES();
1105 42 : }
1106 :
1107 : static PHP_FUNCTION(ob_tidyhandler)
1108 3 : {
1109 : char *input;
1110 : int input_len;
1111 : long mode;
1112 : TidyBuffer errbuf;
1113 : TidyDoc doc;
1114 :
1115 3 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE) {
1116 0 : return;
1117 : }
1118 :
1119 3 : doc = tidyCreate();
1120 3 : tidyBufInit(&errbuf);
1121 :
1122 3 : tidyOptSetBool(doc, TidyForceOutput, yes);
1123 3 : tidyOptSetBool(doc, TidyMark, no);
1124 :
1125 3 : if (tidySetErrorBuffer(doc, &errbuf) != 0) {
1126 0 : tidyRelease(doc);
1127 0 : tidyBufFree(&errbuf);
1128 :
1129 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
1130 : }
1131 :
1132 3 : TIDY_SET_DEFAULT_CONFIG(doc);
1133 :
1134 3 : if (input_len > 1) {
1135 : TidyBuffer buf;
1136 :
1137 2 : tidyBufInit(&buf);
1138 2 : tidyBufAppend(&buf, input, input_len);
1139 :
1140 2 : if (tidyParseBuffer(doc, &buf) < 0 || tidyCleanAndRepair(doc) < 0) {
1141 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf.bp);
1142 0 : RETVAL_NULL();
1143 : } else {
1144 : TidyBuffer output;
1145 2 : tidyBufInit(&output);
1146 :
1147 2 : tidySaveBuffer(doc, &output);
1148 2 : RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
1149 :
1150 2 : tidyBufFree(&output);
1151 : }
1152 :
1153 2 : tidyBufFree(&buf);
1154 : } else {
1155 1 : RETVAL_NULL();
1156 : }
1157 :
1158 3 : tidyRelease(doc);
1159 3 : tidyBufFree(&errbuf);
1160 : }
1161 :
1162 : /* {{{ proto bool tidy_parse_string(string input [, mixed config_options [, string encoding]])
1163 : Parse a document stored in a string */
1164 : static PHP_FUNCTION(tidy_parse_string)
1165 25 : {
1166 25 : char *input, *enc = NULL;
1167 25 : int input_len, enc_len = 0;
1168 25 : zval **options = NULL;
1169 :
1170 : PHPTidyObj *obj;
1171 :
1172 25 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
1173 0 : RETURN_FALSE;
1174 : }
1175 :
1176 25 : tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
1177 25 : obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
1178 :
1179 25 : TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
1180 :
1181 25 : if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == FAILURE) {
1182 0 : zval_dtor(return_value);
1183 0 : INIT_ZVAL(*return_value);
1184 0 : RETURN_FALSE;
1185 : }
1186 :
1187 : }
1188 : /* }}} */
1189 :
1190 : /* {{{ proto string tidy_get_error_buffer([boolean detailed])
1191 : Return warnings and errors which occured parsing the specified document*/
1192 : static PHP_FUNCTION(tidy_get_error_buffer)
1193 2 : {
1194 2 : TIDY_FETCH_OBJECT;
1195 :
1196 2 : if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) {
1197 2 : RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, 1);
1198 : } else {
1199 0 : RETURN_FALSE;
1200 : }
1201 : }
1202 : /* }}} */
1203 :
1204 : /* {{{ proto string tidy_get_output()
1205 : Return a string representing the parsed tidy markup */
1206 : static PHP_FUNCTION(tidy_get_output)
1207 6 : {
1208 : TidyBuffer output;
1209 6 : TIDY_FETCH_OBJECT;
1210 :
1211 6 : tidyBufInit(&output);
1212 6 : tidySaveBuffer(obj->ptdoc->doc, &output);
1213 :
1214 6 : RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
1215 :
1216 6 : tidyBufFree(&output);
1217 : }
1218 : /* }}} */
1219 :
1220 : /* {{{ proto boolean tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])
1221 : Parse markup in file or URI */
1222 : static PHP_FUNCTION(tidy_parse_file)
1223 3 : {
1224 3 : char *inputfile, *enc = NULL;
1225 3 : int input_len, contents_len, enc_len = 0;
1226 3 : zend_bool use_include_path = 0;
1227 : char *contents;
1228 3 : zval **options = NULL;
1229 :
1230 : PHPTidyObj *obj;
1231 :
1232 3 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &inputfile, &input_len,
1233 : &options, &enc, &enc_len, &use_include_path) == FAILURE) {
1234 0 : RETURN_FALSE;
1235 : }
1236 :
1237 3 : tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
1238 3 : obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
1239 :
1240 3 : if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
1241 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
1242 0 : RETURN_FALSE;
1243 : }
1244 :
1245 3 : TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
1246 :
1247 3 : if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
1248 0 : zval_dtor(return_value);
1249 0 : INIT_ZVAL(*return_value);
1250 0 : RETVAL_FALSE;
1251 : }
1252 :
1253 3 : efree(contents);
1254 : }
1255 : /* }}} */
1256 :
1257 : /* {{{ proto boolean tidy_clean_repair()
1258 : Execute configured cleanup and repair operations on parsed markup */
1259 : static PHP_FUNCTION(tidy_clean_repair)
1260 10 : {
1261 10 : TIDY_FETCH_OBJECT;
1262 :
1263 10 : if (tidyCleanAndRepair(obj->ptdoc->doc) >= 0) {
1264 10 : tidy_doc_update_properties(obj TSRMLS_CC);
1265 10 : RETURN_TRUE;
1266 : }
1267 :
1268 0 : RETURN_FALSE;
1269 : }
1270 : /* }}} */
1271 :
1272 : /* {{{ proto boolean tidy_repair_string(string data [, mixed config_file [, string encoding]])
1273 : Repair a string using an optionally provided configuration file */
1274 : static PHP_FUNCTION(tidy_repair_string)
1275 9 : {
1276 9 : php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE);
1277 9 : }
1278 : /* }}} */
1279 :
1280 : /* {{{ proto boolean tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])
1281 : Repair a file using an optionally provided configuration file */
1282 : static PHP_FUNCTION(tidy_repair_file)
1283 8 : {
1284 8 : php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE);
1285 8 : }
1286 : /* }}} */
1287 :
1288 : /* {{{ proto boolean tidy_diagnose()
1289 : Run configured diagnostics on parsed and repaired markup. */
1290 : static PHP_FUNCTION(tidy_diagnose)
1291 3 : {
1292 3 : TIDY_FETCH_OBJECT;
1293 :
1294 3 : if (tidyRunDiagnostics(obj->ptdoc->doc) >= 0) {
1295 3 : tidy_doc_update_properties(obj TSRMLS_CC);
1296 3 : RETURN_TRUE;
1297 : }
1298 :
1299 0 : RETURN_FALSE;
1300 : }
1301 : /* }}} */
1302 :
1303 : /* {{{ proto string tidy_get_release()
1304 : Get release date (version) for Tidy library */
1305 : static PHP_FUNCTION(tidy_get_release)
1306 1 : {
1307 1 : if (zend_parse_parameters_none() == FAILURE) {
1308 0 : return;
1309 : }
1310 :
1311 1 : RETURN_STRING((char *)tidyReleaseDate(), 1);
1312 : }
1313 : /* }}} */
1314 :
1315 :
1316 : #if HAVE_TIDYOPTGETDOC
1317 : /* {{{ proto string tidy_get_opt_doc(tidy resource, string optname)
1318 : Returns the documentation for the given option name */
1319 : static PHP_FUNCTION(tidy_get_opt_doc)
1320 3 : {
1321 : PHPTidyObj *obj;
1322 : char *optname, *optval;
1323 : int optname_len;
1324 : TidyOption opt;
1325 :
1326 3 : TIDY_SET_CONTEXT;
1327 :
1328 3 : if (object) {
1329 1 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) {
1330 0 : RETURN_FALSE;
1331 : }
1332 : } else {
1333 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &optname, &optname_len) == FAILURE) {
1334 0 : RETURN_FALSE;
1335 : }
1336 : }
1337 :
1338 3 : obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
1339 :
1340 3 : opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
1341 :
1342 3 : if (!opt) {
1343 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname);
1344 1 : RETURN_FALSE;
1345 : }
1346 :
1347 2 : if ( (optval = (char *) tidyOptGetDoc(obj->ptdoc->doc, opt)) ) {
1348 2 : RETURN_STRING(optval, 1);
1349 : }
1350 :
1351 0 : RETURN_FALSE;
1352 : }
1353 : /* }}} */
1354 : #endif
1355 :
1356 :
1357 : /* {{{ proto array tidy_get_config()
1358 : Get current Tidy configuarion */
1359 : static PHP_FUNCTION(tidy_get_config)
1360 1 : {
1361 : TidyIterator itOpt;
1362 : char *opt_name;
1363 : void *opt_value;
1364 : TidyOptionType optt;
1365 :
1366 1 : TIDY_FETCH_OBJECT;
1367 :
1368 1 : itOpt = tidyGetOptionList(obj->ptdoc->doc);
1369 :
1370 1 : array_init(return_value);
1371 :
1372 89 : while (itOpt) {
1373 87 : TidyOption opt = tidyGetNextOption(obj->ptdoc->doc, &itOpt);
1374 :
1375 87 : opt_name = (char *)tidyOptGetName(opt);
1376 87 : opt_value = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
1377 87 : switch (optt) {
1378 : case TidyString:
1379 12 : add_assoc_string(return_value, opt_name, (char*)opt_value, 0);
1380 12 : break;
1381 :
1382 : case TidyInteger:
1383 17 : add_assoc_long(return_value, opt_name, (long)opt_value);
1384 17 : break;
1385 :
1386 : case TidyBoolean:
1387 58 : add_assoc_bool(return_value, opt_name, (long)opt_value);
1388 : break;
1389 : }
1390 : }
1391 :
1392 1 : return;
1393 : }
1394 : /* }}} */
1395 :
1396 : /* {{{ proto int tidy_get_status()
1397 : Get status of specfied document. */
1398 : static PHP_FUNCTION(tidy_get_status)
1399 3 : {
1400 3 : TIDY_FETCH_OBJECT;
1401 :
1402 3 : RETURN_LONG(tidyStatus(obj->ptdoc->doc));
1403 : }
1404 : /* }}} */
1405 :
1406 : /* {{{ proto int tidy_get_html_ver()
1407 : Get the Detected HTML version for the specified document. */
1408 : static PHP_FUNCTION(tidy_get_html_ver)
1409 0 : {
1410 0 : TIDY_FETCH_OBJECT;
1411 :
1412 0 : RETURN_LONG(tidyDetectedHtmlVersion(obj->ptdoc->doc));
1413 : }
1414 : /* }}} */
1415 :
1416 : /* {{{ proto boolean tidy_is_xhtml()
1417 : Indicates if the document is a XHTML document. */
1418 : static PHP_FUNCTION(tidy_is_xhtml)
1419 0 : {
1420 0 : TIDY_FETCH_OBJECT;
1421 :
1422 0 : RETURN_BOOL(tidyDetectedXhtml(obj->ptdoc->doc));
1423 : }
1424 : /* }}} */
1425 :
1426 : /* {{{ proto boolean tidy_is_xml()
1427 : Indicates if the document is a generic (non HTML/XHTML) XML document. */
1428 : static PHP_FUNCTION(tidy_is_xml)
1429 0 : {
1430 0 : TIDY_FETCH_OBJECT;
1431 :
1432 0 : RETURN_BOOL(tidyDetectedGenericXml(obj->ptdoc->doc));
1433 : }
1434 : /* }}} */
1435 :
1436 : /* {{{ proto int tidy_error_count()
1437 : Returns the Number of Tidy errors encountered for specified document. */
1438 : static PHP_FUNCTION(tidy_error_count)
1439 1 : {
1440 1 : TIDY_FETCH_OBJECT;
1441 :
1442 1 : RETURN_LONG(tidyErrorCount(obj->ptdoc->doc));
1443 : }
1444 : /* }}} */
1445 :
1446 : /* {{{ proto int tidy_warning_count()
1447 : Returns the Number of Tidy warnings encountered for specified document. */
1448 : static PHP_FUNCTION(tidy_warning_count)
1449 2 : {
1450 2 : TIDY_FETCH_OBJECT;
1451 :
1452 2 : RETURN_LONG(tidyWarningCount(obj->ptdoc->doc));
1453 : }
1454 : /* }}} */
1455 :
1456 : /* {{{ proto int tidy_access_count()
1457 : Returns the Number of Tidy accessibility warnings encountered for specified document. */
1458 : static PHP_FUNCTION(tidy_access_count)
1459 1 : {
1460 1 : TIDY_FETCH_OBJECT;
1461 :
1462 1 : RETURN_LONG(tidyAccessWarningCount(obj->ptdoc->doc));
1463 : }
1464 : /* }}} */
1465 :
1466 : /* {{{ proto int tidy_config_count()
1467 : Returns the Number of Tidy configuration errors encountered for specified document. */
1468 : static PHP_FUNCTION(tidy_config_count)
1469 1 : {
1470 1 : TIDY_FETCH_OBJECT;
1471 :
1472 1 : RETURN_LONG(tidyConfigErrorCount(obj->ptdoc->doc));
1473 : }
1474 : /* }}} */
1475 :
1476 : /* {{{ proto mixed tidy_getopt(string option)
1477 : Returns the value of the specified configuration option for the tidy document. */
1478 : static PHP_FUNCTION(tidy_getopt)
1479 5 : {
1480 : PHPTidyObj *obj;
1481 : char *optname;
1482 : void *optval;
1483 : int optname_len;
1484 : TidyOption opt;
1485 : TidyOptionType optt;
1486 :
1487 5 : TIDY_SET_CONTEXT;
1488 :
1489 5 : if (object) {
1490 4 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) {
1491 0 : RETURN_FALSE;
1492 : }
1493 : } else {
1494 1 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &optname, &optname_len) == FAILURE) {
1495 0 : RETURN_FALSE;
1496 : }
1497 : }
1498 :
1499 5 : obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
1500 :
1501 5 : opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
1502 :
1503 5 : if (!opt) {
1504 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname);
1505 2 : RETURN_FALSE;
1506 : }
1507 :
1508 3 : optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
1509 3 : switch (optt) {
1510 : case TidyString:
1511 1 : RETURN_STRING((char *)optval, 0);
1512 : break;
1513 :
1514 : case TidyInteger:
1515 1 : RETURN_LONG((long)optval);
1516 : break;
1517 :
1518 : case TidyBoolean:
1519 1 : if (optval) {
1520 0 : RETURN_TRUE;
1521 : } else {
1522 1 : RETURN_FALSE;
1523 : }
1524 : break;
1525 :
1526 : default:
1527 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of configuration option");
1528 : break;
1529 : }
1530 :
1531 0 : RETURN_FALSE;
1532 : }
1533 : /* }}} */
1534 :
1535 : static TIDY_DOC_METHOD(__construct)
1536 11 : {
1537 11 : char *inputfile = NULL, *enc = NULL;
1538 11 : int input_len = 0, enc_len = 0, contents_len = 0;
1539 11 : zend_bool use_include_path = 0;
1540 : char *contents;
1541 11 : zval **options = NULL;
1542 :
1543 : PHPTidyObj *obj;
1544 11 : TIDY_SET_CONTEXT;
1545 :
1546 11 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sZsb", &inputfile, &input_len,
1547 : &options, &enc, &enc_len, &use_include_path) == FAILURE) {
1548 0 : RETURN_FALSE;
1549 : }
1550 :
1551 11 : obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
1552 :
1553 11 : if (inputfile) {
1554 2 : if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
1555 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
1556 0 : return;
1557 : }
1558 :
1559 2 : TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
1560 :
1561 2 : php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC);
1562 :
1563 2 : efree(contents);
1564 : }
1565 : }
1566 :
1567 : static TIDY_DOC_METHOD(parseFile)
1568 0 : {
1569 0 : char *inputfile, *enc = NULL;
1570 0 : int input_len, enc_len = 0, contents_len = 0;
1571 0 : zend_bool use_include_path = 0;
1572 : char *contents;
1573 0 : zval **options = NULL;
1574 : PHPTidyObj *obj;
1575 :
1576 0 : TIDY_SET_CONTEXT;
1577 :
1578 0 : obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
1579 :
1580 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &inputfile, &input_len,
1581 : &options, &enc, &enc_len, &use_include_path) == FAILURE) {
1582 0 : RETURN_FALSE;
1583 : }
1584 :
1585 0 : if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
1586 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
1587 0 : RETURN_FALSE;
1588 : }
1589 :
1590 0 : TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
1591 :
1592 0 : if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
1593 0 : RETVAL_FALSE;
1594 : } else {
1595 0 : RETVAL_TRUE;
1596 : }
1597 :
1598 0 : efree(contents);
1599 : }
1600 :
1601 : static TIDY_DOC_METHOD(parseString)
1602 5 : {
1603 5 : char *input, *enc = NULL;
1604 5 : int input_len, enc_len = 0;
1605 5 : zval **options = NULL;
1606 : PHPTidyObj *obj;
1607 :
1608 5 : TIDY_SET_CONTEXT;
1609 :
1610 5 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
1611 0 : RETURN_FALSE;
1612 : }
1613 :
1614 5 : obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
1615 :
1616 5 : TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
1617 :
1618 5 : if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == SUCCESS) {
1619 5 : RETURN_TRUE;
1620 : }
1621 :
1622 0 : RETURN_FALSE;
1623 : }
1624 :
1625 :
1626 : /* {{{ proto TidyNode tidy_get_root()
1627 : Returns a TidyNode Object representing the root of the tidy parse tree */
1628 : static PHP_FUNCTION(tidy_get_root)
1629 14 : {
1630 14 : php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_root_node);
1631 14 : }
1632 : /* }}} */
1633 :
1634 : /* {{{ proto TidyNode tidy_get_html()
1635 : Returns a TidyNode Object starting from the <HTML> tag of the tidy parse tree */
1636 : static PHP_FUNCTION(tidy_get_html)
1637 2 : {
1638 2 : php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_html_node);
1639 2 : }
1640 : /* }}} */
1641 :
1642 : /* {{{ proto TidyNode tidy_get_head()
1643 : Returns a TidyNode Object starting from the <HEAD> tag of the tidy parse tree */
1644 : static PHP_FUNCTION(tidy_get_head)
1645 1 : {
1646 1 : php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_head_node);
1647 1 : }
1648 : /* }}} */
1649 :
1650 : /* {{{ proto TidyNode tidy_get_body(resource tidy)
1651 : Returns a TidyNode Object starting from the <BODY> tag of the tidy parse tree */
1652 : static PHP_FUNCTION(tidy_get_body)
1653 6 : {
1654 6 : php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_body_node);
1655 6 : }
1656 : /* }}} */
1657 :
1658 : /* {{{ proto boolean tidyNode::hasChildren()
1659 : Returns true if this node has children */
1660 : static TIDY_NODE_METHOD(hasChildren)
1661 23 : {
1662 23 : TIDY_FETCH_ONLY_OBJECT;
1663 :
1664 23 : if (tidyGetChild(obj->node)) {
1665 18 : RETURN_TRUE;
1666 : } else {
1667 5 : RETURN_FALSE;
1668 : }
1669 : }
1670 : /* }}} */
1671 :
1672 : /* {{{ proto boolean tidyNode::hasSiblings()
1673 : Returns true if this node has siblings */
1674 : static TIDY_NODE_METHOD(hasSiblings)
1675 2 : {
1676 2 : TIDY_FETCH_ONLY_OBJECT;
1677 :
1678 2 : if (obj->node && tidyGetNext(obj->node)) {
1679 1 : RETURN_TRUE;
1680 : } else {
1681 1 : RETURN_FALSE;
1682 : }
1683 : }
1684 : /* }}} */
1685 :
1686 : /* {{{ proto boolean tidyNode::isComment()
1687 : Returns true if this node represents a comment */
1688 : static TIDY_NODE_METHOD(isComment)
1689 2 : {
1690 2 : TIDY_FETCH_ONLY_OBJECT;
1691 :
1692 2 : if (tidyNodeGetType(obj->node) == TidyNode_Comment) {
1693 1 : RETURN_TRUE;
1694 : } else {
1695 1 : RETURN_FALSE;
1696 : }
1697 : }
1698 : /* }}} */
1699 :
1700 : /* {{{ proto boolean tidyNode::isHtml()
1701 : Returns true if this node is part of a HTML document */
1702 : static TIDY_NODE_METHOD(isHtml)
1703 2 : {
1704 2 : TIDY_FETCH_ONLY_OBJECT;
1705 :
1706 2 : if (tidyNodeGetType(obj->node) & (TidyNode_Start | TidyNode_End | TidyNode_StartEnd)) {
1707 1 : RETURN_TRUE;
1708 : }
1709 :
1710 1 : RETURN_FALSE;
1711 : }
1712 : /* }}} */
1713 :
1714 : /* {{{ proto boolean tidyNode::isText()
1715 : Returns true if this node represents text (no markup) */
1716 : static TIDY_NODE_METHOD(isText)
1717 2 : {
1718 2 : TIDY_FETCH_ONLY_OBJECT;
1719 :
1720 2 : if (tidyNodeGetType(obj->node) == TidyNode_Text) {
1721 1 : RETURN_TRUE;
1722 : } else {
1723 1 : RETURN_FALSE;
1724 : }
1725 : }
1726 : /* }}} */
1727 :
1728 : /* {{{ proto boolean tidyNode::isJste()
1729 : Returns true if this node is JSTE */
1730 : static TIDY_NODE_METHOD(isJste)
1731 2 : {
1732 2 : TIDY_FETCH_ONLY_OBJECT;
1733 :
1734 2 : if (tidyNodeGetType(obj->node) == TidyNode_Jste) {
1735 1 : RETURN_TRUE;
1736 : } else {
1737 1 : RETURN_FALSE;
1738 : }
1739 : }
1740 : /* }}} */
1741 :
1742 : /* {{{ proto boolean tidyNode::isAsp()
1743 : Returns true if this node is ASP */
1744 : static TIDY_NODE_METHOD(isAsp)
1745 2 : {
1746 2 : TIDY_FETCH_ONLY_OBJECT;
1747 :
1748 2 : if (tidyNodeGetType(obj->node) == TidyNode_Asp) {
1749 1 : RETURN_TRUE;
1750 : } else {
1751 1 : RETURN_FALSE;
1752 : }
1753 : }
1754 : /* }}} */
1755 :
1756 : /* {{{ proto boolean tidyNode::isPhp()
1757 : Returns true if this node is PHP */
1758 : static TIDY_NODE_METHOD(isPhp)
1759 2 : {
1760 2 : TIDY_FETCH_ONLY_OBJECT;
1761 :
1762 2 : if (tidyNodeGetType(obj->node) == TidyNode_Php) {
1763 1 : RETURN_TRUE;
1764 : } else {
1765 1 : RETURN_FALSE;
1766 : }
1767 : }
1768 : /* }}} */
1769 :
1770 : /* {{{ proto tidyNode tidyNode::getParent()
1771 : Returns the parent node if available or NULL */
1772 : static TIDY_NODE_METHOD(getParent)
1773 2 : {
1774 : TidyNode parent_node;
1775 : PHPTidyObj *newobj;
1776 2 : TIDY_FETCH_ONLY_OBJECT;
1777 :
1778 2 : parent_node = tidyGetParent(obj->node);
1779 2 : if(parent_node) {
1780 1 : tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
1781 1 : newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
1782 1 : newobj->node = parent_node;
1783 1 : newobj->type = is_node;
1784 1 : newobj->ptdoc = obj->ptdoc;
1785 1 : newobj->ptdoc->ref_count++;
1786 1 : tidy_add_default_properties(newobj, is_node TSRMLS_CC);
1787 : } else {
1788 1 : ZVAL_NULL(return_value);
1789 : }
1790 : }
1791 : /* }}} */
1792 :
1793 : static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS)
1794 17633 : {
1795 17633 : TIDY_NODE_CONST(ROOT, Root);
1796 17633 : TIDY_NODE_CONST(DOCTYPE, DocType);
1797 17633 : TIDY_NODE_CONST(COMMENT, Comment);
1798 17633 : TIDY_NODE_CONST(PROCINS, ProcIns);
1799 17633 : TIDY_NODE_CONST(TEXT, Text);
1800 17633 : TIDY_NODE_CONST(START, Start);
1801 17633 : TIDY_NODE_CONST(END, End);
1802 17633 : TIDY_NODE_CONST(STARTEND, StartEnd);
1803 17633 : TIDY_NODE_CONST(CDATA, CDATA);
1804 17633 : TIDY_NODE_CONST(SECTION, Section);
1805 17633 : TIDY_NODE_CONST(ASP, Asp);
1806 17633 : TIDY_NODE_CONST(JSTE, Jste);
1807 17633 : TIDY_NODE_CONST(PHP, Php);
1808 17633 : TIDY_NODE_CONST(XMLDECL, XmlDecl);
1809 17633 : }
1810 :
1811 : static void _php_tidy_register_tags(INIT_FUNC_ARGS)
1812 17633 : {
1813 17633 : TIDY_TAG_CONST(UNKNOWN);
1814 17633 : TIDY_TAG_CONST(A);
1815 17633 : TIDY_TAG_CONST(ABBR);
1816 17633 : TIDY_TAG_CONST(ACRONYM);
1817 17633 : TIDY_TAG_CONST(ADDRESS);
1818 17633 : TIDY_TAG_CONST(ALIGN);
1819 17633 : TIDY_TAG_CONST(APPLET);
1820 17633 : TIDY_TAG_CONST(AREA);
1821 17633 : TIDY_TAG_CONST(B);
1822 17633 : TIDY_TAG_CONST(BASE);
1823 17633 : TIDY_TAG_CONST(BASEFONT);
1824 17633 : TIDY_TAG_CONST(BDO);
1825 17633 : TIDY_TAG_CONST(BGSOUND);
1826 17633 : TIDY_TAG_CONST(BIG);
1827 17633 : TIDY_TAG_CONST(BLINK);
1828 17633 : TIDY_TAG_CONST(BLOCKQUOTE);
1829 17633 : TIDY_TAG_CONST(BODY);
1830 17633 : TIDY_TAG_CONST(BR);
1831 17633 : TIDY_TAG_CONST(BUTTON);
1832 17633 : TIDY_TAG_CONST(CAPTION);
1833 17633 : TIDY_TAG_CONST(CENTER);
1834 17633 : TIDY_TAG_CONST(CITE);
1835 17633 : TIDY_TAG_CONST(CODE);
1836 17633 : TIDY_TAG_CONST(COL);
1837 17633 : TIDY_TAG_CONST(COLGROUP);
1838 17633 : TIDY_TAG_CONST(COMMENT);
1839 17633 : TIDY_TAG_CONST(DD);
1840 17633 : TIDY_TAG_CONST(DEL);
1841 17633 : TIDY_TAG_CONST(DFN);
1842 17633 : TIDY_TAG_CONST(DIR);
1843 17633 : TIDY_TAG_CONST(DIV);
1844 17633 : TIDY_TAG_CONST(DL);
1845 17633 : TIDY_TAG_CONST(DT);
1846 17633 : TIDY_TAG_CONST(EM);
1847 17633 : TIDY_TAG_CONST(EMBED);
1848 17633 : TIDY_TAG_CONST(FIELDSET);
1849 17633 : TIDY_TAG_CONST(FONT);
1850 17633 : TIDY_TAG_CONST(FORM);
1851 17633 : TIDY_TAG_CONST(FRAME);
1852 17633 : TIDY_TAG_CONST(FRAMESET);
1853 17633 : TIDY_TAG_CONST(H1);
1854 17633 : TIDY_TAG_CONST(H2);
1855 17633 : TIDY_TAG_CONST(H3);
1856 17633 : TIDY_TAG_CONST(H4);
1857 17633 : TIDY_TAG_CONST(H5);
1858 17633 : TIDY_TAG_CONST(H6);
1859 17633 : TIDY_TAG_CONST(HEAD);
1860 17633 : TIDY_TAG_CONST(HR);
1861 17633 : TIDY_TAG_CONST(HTML);
1862 17633 : TIDY_TAG_CONST(I);
1863 17633 : TIDY_TAG_CONST(IFRAME);
1864 17633 : TIDY_TAG_CONST(ILAYER);
1865 17633 : TIDY_TAG_CONST(IMG);
1866 17633 : TIDY_TAG_CONST(INPUT);
1867 17633 : TIDY_TAG_CONST(INS);
1868 17633 : TIDY_TAG_CONST(ISINDEX);
1869 17633 : TIDY_TAG_CONST(KBD);
1870 17633 : TIDY_TAG_CONST(KEYGEN);
1871 17633 : TIDY_TAG_CONST(LABEL);
1872 17633 : TIDY_TAG_CONST(LAYER);
1873 17633 : TIDY_TAG_CONST(LEGEND);
1874 17633 : TIDY_TAG_CONST(LI);
1875 17633 : TIDY_TAG_CONST(LINK);
1876 17633 : TIDY_TAG_CONST(LISTING);
1877 17633 : TIDY_TAG_CONST(MAP);
1878 17633 : TIDY_TAG_CONST(MARQUEE);
1879 17633 : TIDY_TAG_CONST(MENU);
1880 17633 : TIDY_TAG_CONST(META);
1881 17633 : TIDY_TAG_CONST(MULTICOL);
1882 17633 : TIDY_TAG_CONST(NOBR);
1883 17633 : TIDY_TAG_CONST(NOEMBED);
1884 17633 : TIDY_TAG_CONST(NOFRAMES);
1885 17633 : TIDY_TAG_CONST(NOLAYER);
1886 17633 : TIDY_TAG_CONST(NOSAVE);
1887 17633 : TIDY_TAG_CONST(NOSCRIPT);
1888 17633 : TIDY_TAG_CONST(OBJECT);
1889 17633 : TIDY_TAG_CONST(OL);
1890 17633 : TIDY_TAG_CONST(OPTGROUP);
1891 17633 : TIDY_TAG_CONST(OPTION);
1892 17633 : TIDY_TAG_CONST(P);
1893 17633 : TIDY_TAG_CONST(PARAM);
1894 17633 : TIDY_TAG_CONST(PLAINTEXT);
1895 17633 : TIDY_TAG_CONST(PRE);
1896 17633 : TIDY_TAG_CONST(Q);
1897 17633 : TIDY_TAG_CONST(RB);
1898 17633 : TIDY_TAG_CONST(RBC);
1899 17633 : TIDY_TAG_CONST(RP);
1900 17633 : TIDY_TAG_CONST(RT);
1901 17633 : TIDY_TAG_CONST(RTC);
1902 17633 : TIDY_TAG_CONST(RUBY);
1903 17633 : TIDY_TAG_CONST(S);
1904 17633 : TIDY_TAG_CONST(SAMP);
1905 17633 : TIDY_TAG_CONST(SCRIPT);
1906 17633 : TIDY_TAG_CONST(SELECT);
1907 17633 : TIDY_TAG_CONST(SERVER);
1908 17633 : TIDY_TAG_CONST(SERVLET);
1909 17633 : TIDY_TAG_CONST(SMALL);
1910 17633 : TIDY_TAG_CONST(SPACER);
1911 17633 : TIDY_TAG_CONST(SPAN);
1912 17633 : TIDY_TAG_CONST(STRIKE);
1913 17633 : TIDY_TAG_CONST(STRONG);
1914 17633 : TIDY_TAG_CONST(STYLE);
1915 17633 : TIDY_TAG_CONST(SUB);
1916 17633 : TIDY_TAG_CONST(SUP);
1917 17633 : TIDY_TAG_CONST(TABLE);
1918 17633 : TIDY_TAG_CONST(TBODY);
1919 17633 : TIDY_TAG_CONST(TD);
1920 17633 : TIDY_TAG_CONST(TEXTAREA);
1921 17633 : TIDY_TAG_CONST(TFOOT);
1922 17633 : TIDY_TAG_CONST(TH);
1923 17633 : TIDY_TAG_CONST(THEAD);
1924 17633 : TIDY_TAG_CONST(TITLE);
1925 17633 : TIDY_TAG_CONST(TR);
1926 17633 : TIDY_TAG_CONST(TT);
1927 17633 : TIDY_TAG_CONST(U);
1928 17633 : TIDY_TAG_CONST(UL);
1929 17633 : TIDY_TAG_CONST(VAR);
1930 17633 : TIDY_TAG_CONST(WBR);
1931 17633 : TIDY_TAG_CONST(XMP);
1932 17633 : }
1933 :
1934 : #endif
1935 :
1936 : /*
1937 : * Local variables:
1938 : * tab-width: 4
1939 : * c-basic-offset: 4
1940 : * End:
1941 : * vim600: noet sw=4 ts=4 fdm=marker
1942 : * vim<600: noet sw=4 ts=4
1943 : */
|