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