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