From 4cd101abed1d233eba6e07d974a002db071b57c1 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sat, 20 Sep 2003 19:45:32 +0000 Subject: [PATCH] Tidy Hijacked! Read all about it ;) * No more tidy resources, it's now persistent and internal. This helps speed quite a bit, since the tidy resource only needs to be initialized once. * Replace common code with macros. * Added necessary safe_mode & open_basedir checks when working with files. * Added ini option to allow loading of config file on startup. * Show current configuration in phpinfo(); * Coding Style Cleanup * Added tidy_get_config(), returns an associated array with all configuration values. * Added tidy_reset_config(), it restores tidy configuration to default values. * Fixed a possible crash inside tidy_setopt(). * Added myself to the credits. More changes to follow. --- ext/tidy/CREDITS | 2 +- ext/tidy/package.xml | 6 + ext/tidy/php_tidy.h | 27 +- ext/tidy/tidy.c | 1392 ++++++++++++++++-------------------------- 4 files changed, 560 insertions(+), 867 deletions(-) diff --git a/ext/tidy/CREDITS b/ext/tidy/CREDITS index e6d6eb252d..1c77b2ff3b 100644 --- a/ext/tidy/CREDITS +++ b/ext/tidy/CREDITS @@ -1,2 +1,2 @@ tidy -John Coggeshall \ No newline at end of file +John Coggeshall, Ilia Alshanetsky diff --git a/ext/tidy/package.xml b/ext/tidy/package.xml index eed7ed0bf5..d5c186ebce 100644 --- a/ext/tidy/package.xml +++ b/ext/tidy/package.xml @@ -10,6 +10,12 @@ john@php.net lead + + iliaa + Ilia Alshanetsky + ilia@php.net + lead + Tidy is a binding for the Tidy HTML clean and repair utility which diff --git a/ext/tidy/php_tidy.h b/ext/tidy/php_tidy.h index 9ba85f4c86..1723c0b0b8 100644 --- a/ext/tidy/php_tidy.h +++ b/ext/tidy/php_tidy.h @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: John Coggeshall | + | Ilia Alshanetsky | +----------------------------------------------------------------------+ */ @@ -39,9 +40,9 @@ extern zend_module_entry tidy_module_entry; #include "buffio.h" #ifdef ZTS -#define TIDY_G(v) TSRMG(tidy_globals_id, zend_tidy_globals *, v) +#define TG(v) TSRMG(tidy_globals_id, zend_tidy_globals *, v) #else -#define TIDY_G(v) (tidy_globals.v) +#define TG(v) (tidy_globals.v) #endif #ifndef TRUE @@ -77,7 +78,6 @@ struct _PHPTidyObj { zend_object obj; TidyNode node; TidyAttr attr; - PHPTidyDoc *tdoc; unsigned int type; PHPTidyObj *parent; unsigned int refcount; @@ -90,7 +90,6 @@ PHP_RINIT_FUNCTION(tidy); PHP_RSHUTDOWN_FUNCTION(tidy); PHP_MINFO_FUNCTION(tidy); -PHP_FUNCTION(tidy_create); PHP_FUNCTION(tidy_setopt); PHP_FUNCTION(tidy_getopt); PHP_FUNCTION(tidy_parse_string); @@ -100,6 +99,8 @@ PHP_FUNCTION(tidy_diagnose); PHP_FUNCTION(tidy_get_output); PHP_FUNCTION(tidy_get_error_buffer); PHP_FUNCTION(tidy_get_release); +PHP_FUNCTION(tidy_reset_config); +PHP_FUNCTION(tidy_get_config); PHP_FUNCTION(tidy_get_status); PHP_FUNCTION(tidy_get_html_ver); PHP_FUNCTION(tidy_is_xhtml); @@ -167,19 +168,17 @@ void _php_tidy_register_nodetypes(INIT_FUNC_ARGS); void _php_tidy_register_tags(INIT_FUNC_ARGS); void _php_tidy_register_attributes(INIT_FUNC_ARGS); -/* Callbacks for hooking Tidy Memory alloc into e*alloc */ -void * _php_tidy_mem_alloc(size_t size); -void * _php_tidy_mem_realloc(void *mem, size_t newsize); -void _php_tidy_mem_free(void *mem); -void _php_tidy_mem_panic(ctmbstr errmsg); - ZEND_BEGIN_MODULE_GLOBALS(tidy) + PHPTidyDoc *tdoc; + zend_bool used; + char *default_config; ZEND_END_MODULE_GLOBALS(tidy) - - - - +#ifdef ZTS +#define TG(v) TSRMG(tidy_globals_id, zend_tidy_globals *, v) +#else +#define TG(v) (tidy_globals.v) +#endif #endif diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index e80dc1244a..26a5179733 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: John Coggeshall | + | Ilia Alshanetsky | +----------------------------------------------------------------------+ */ @@ -38,8 +39,21 @@ ZEND_DECLARE_MODULE_GLOBALS(tidy); +/* static int le_tidydoc; #define le_tidydoc_name "Tidy Document" +*/ + +#define TIDY_PARSED_CHECK() \ +if(!TG(tdoc)->parsed) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); \ + RETURN_FALSE; \ +} \ + +#define TIDY_SAFE_MODE_CHECK(filename) \ +if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) { \ + RETURN_FALSE; \ +} \ #ifdef ZEND_ENGINE_2 @@ -71,7 +85,6 @@ static zend_object_handlers php_tidy_object_handlers = { #endif function_entry tidy_functions[] = { - PHP_FE(tidy_create, NULL) PHP_FE(tidy_setopt, NULL) PHP_FE(tidy_getopt, NULL) PHP_FE(tidy_parse_string, NULL) @@ -80,25 +93,26 @@ function_entry tidy_functions[] = { PHP_FE(tidy_get_error_buffer, NULL) PHP_FE(tidy_clean_repair, NULL) PHP_FE(tidy_diagnose, NULL) - PHP_FE(tidy_get_release, NULL) - PHP_FE(tidy_get_status, NULL) - PHP_FE(tidy_get_html_ver, NULL) - PHP_FE(tidy_is_xhtml, NULL) - PHP_FE(tidy_is_xml, NULL) - PHP_FE(tidy_error_count, NULL) - PHP_FE(tidy_warning_count, NULL) - PHP_FE(tidy_access_count, NULL) - PHP_FE(tidy_config_count, NULL) - PHP_FE(tidy_load_config, NULL) + PHP_FE(tidy_get_release, NULL) + PHP_FE(tidy_get_config, NULL) + PHP_FE(tidy_get_status, NULL) + PHP_FE(tidy_get_html_ver, NULL) + PHP_FE(tidy_is_xhtml, NULL) + PHP_FE(tidy_is_xml, NULL) + PHP_FE(tidy_error_count, NULL) + PHP_FE(tidy_warning_count, NULL) + PHP_FE(tidy_access_count, NULL) + PHP_FE(tidy_config_count, NULL) + PHP_FE(tidy_load_config, NULL) PHP_FE(tidy_load_config_enc, NULL) - PHP_FE(tidy_set_encoding, NULL) - PHP_FE(tidy_save_config, NULL) + PHP_FE(tidy_set_encoding, NULL) + PHP_FE(tidy_save_config, NULL) #ifdef ZEND_ENGINE_2 - PHP_FE(tidy_get_root, NULL) - PHP_FE(tidy_get_head, NULL) - PHP_FE(tidy_get_html, NULL) - PHP_FE(tidy_get_body, NULL) + PHP_FE(tidy_get_root, NULL) + PHP_FE(tidy_get_head, NULL) + PHP_FE(tidy_get_html, NULL) + PHP_FE(tidy_get_body, NULL) #endif {NULL, NULL, NULL} @@ -113,7 +127,7 @@ zend_module_entry tidy_module_entry = { tidy_functions, PHP_MINIT(tidy), PHP_MSHUTDOWN(tidy), - NULL, + PHP_RINIT(tidy), NULL, PHP_MINFO(tidy), #if ZEND_MODULE_API_NO >= 20010901 @@ -122,22 +136,83 @@ zend_module_entry tidy_module_entry = { STANDARD_MODULE_PROPERTIES }; - #ifdef COMPILE_DL_TIDY ZEND_GET_MODULE(tidy) #endif +/* {{{ PHP_INI + */ +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals) +PHP_INI_END() +/* }}} */ + +static void tidy_globals_ctor(zend_tidy_globals *g TSRMLS_DC) +{ + g->used = 0; + g->tdoc = pemalloc(sizeof(PHPTidyDoc), 1); + g->tdoc->doc = tidyCreate(); + g->tdoc->parsed = 0; + g->tdoc->errbuf = pemalloc(sizeof(TidyBuffer), 1); + tidyBufInit(g->tdoc->errbuf); + + if(tidySetErrorBuffer(g->tdoc->doc, g->tdoc->errbuf) != 0) { + zend_error(E_ERROR, "Could not set Tidy error buffer"); + } + + tidyOptSetBool(g->tdoc->doc, TidyForceOutput, yes); + tidyOptSetBool(g->tdoc->doc, TidyMark, no); + + /* remember settings so that we can restore them */ + tidyOptSnapshot(g->tdoc->doc); +} + +static void tidy_globals_dtor(zend_tidy_globals *g TSRMLS_DC) +{ + tidyBufFree(g->tdoc->errbuf); + pefree(g->tdoc->errbuf, 1); + tidyRelease(g->tdoc->doc); + pefree(g->tdoc, 1); + g->used = 0; +} + +static void *_php_tidy_get_opt_val(TidyOption opt, TidyOptionType *type) +{ + *type = tidyOptGetType(opt); + + switch (*type) { + case TidyString: { + char *val = (char *) tidyOptGetValue(TG(tdoc)->doc, tidyOptGetId(opt)); + if (val) { + return (void *) estrdup(val); + } else { + return (void *) estrdup(""); + } + } + break; + + case TidyInteger: + return (void *) tidyOptGetInt(TG(tdoc)->doc, tidyOptGetId(opt)); + break; + + case TidyBoolean: + return (void *) tidyOptGetBool(TG(tdoc)->doc, tidyOptGetId(opt)); + break; + } + + /* should not happen */ + return NULL; +} + #ifdef ZEND_ENGINE_2 static inline PHPTidyObj *php_tidy_fetch_object(zval *object TSRMLS_DC) { - return (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); } PHPTidyObj *php_tidy_new() { - PHPTidyObj *intern; intern = emalloc(sizeof(PHPTidyObj)); @@ -147,14 +222,12 @@ PHPTidyObj *php_tidy_new() intern->node = NULL; intern->attr = NULL; intern->type = PHP_IS_TIDYUNDEF; - intern->tdoc = NULL; intern->parent = NULL; - + ALLOC_HASHTABLE(intern->obj.properties); zend_hash_init(intern->obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); - + return intern; - } zval *_php_tidy_create_obj_zval(unsigned int objtype, @@ -165,7 +238,7 @@ zval *_php_tidy_create_obj_zval(unsigned int objtype, zval *return_value; MAKE_STD_ZVAL(return_value); ZVAL_NULL(return_value); - + _php_tidy_create_obj(return_value, objtype, parent, data TSRMLS_CC); return return_value; } @@ -176,22 +249,21 @@ void _php_tidy_create_obj(zval *return_value, void *data TSRMLS_DC) { - + PHPTidyObj *retobj, *t; - + retobj = php_tidy_new(); - retobj->tdoc = parent->tdoc; retobj->type = objtype; retobj->refcount = 1; retobj->parent = parent; - + t = retobj; while((t = t->parent)) { t->refcount++; } - + parent->refcount++; - + switch(objtype) { case PHP_IS_TIDYNODE: retobj->node = (TidyNode)data; @@ -212,9 +284,9 @@ void _php_tidy_create_obj(zval *return_value, zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) { - + zend_object_value retval; - + retval.handle = zend_objects_store_put(intern, php_tidy_obj_dtor, php_tidy_obj_clone TSRMLS_CC); @@ -227,13 +299,13 @@ zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) { PHPTidyObj *o = (PHPTidyObj *)object; - + do { o->refcount--; } while((o = o->parent)); - + o = (PHPTidyObj *)object; - + if(o->refcount <= 0) { /* We don't free anything else here from PHPTidyObj, they are all pointers @@ -249,17 +321,16 @@ zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) o->node = NULL; o->attr = NULL; - o->tdoc = NULL; o->type = PHP_IS_TIDYUNDEF; o->parent = NULL; efree(o); } - + } void php_tidy_obj_clone(void *object, void **object_clone TSRMLS_DC) { - + PHPTidyObj *intern = (PHPTidyObj *) object; PHPTidyObj **intern_clone = (PHPTidyObj **) object_clone; @@ -268,337 +339,226 @@ zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) (*intern_clone)->obj.in_get = 0; (*intern_clone)->obj.in_set = 0; ALLOC_HASHTABLE((*intern_clone)->obj.properties); - + /* memcopy these.. */ memcpy((*intern_clone)->node, intern->node, sizeof(TidyNode)); memcpy((*intern_clone)->attr, intern->attr, sizeof(TidyAttr)); - memcpy((*intern_clone)->tdoc, intern->tdoc, sizeof(PHPTidyDoc)); (*intern_clone)->type = intern->type; - -} -#endif - -void * _php_tidy_mem_alloc(size_t size) -{ - return emalloc(size); } -void * _php_tidy_mem_realloc(void *mem, size_t newsize) -{ - return erealloc(mem, newsize); -} - -void _php_tidy_mem_free(void *mem) -{ - efree(mem); -} - -void _php_tidy_mem_panic(ctmbstr errmsg) -{ - - TSRMLS_FETCH(); - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not allocate memory for Tidy: %s", (char *)errmsg); -} - - -void dtor_TidyDoc(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - - PHPTidyDoc *tdoc = (PHPTidyDoc *)rsrc->ptr; - - if(tdoc->doc) { - tidyRelease(tdoc->doc); - } - if(tdoc->errbuf) { - tidyBufFree(tdoc->errbuf); - efree(tdoc->errbuf); - - } - - efree(tdoc); - -} - -void php_tidy_init_globals(zend_tidy_globals *tidy_globals) -{ - - /* No globals for now */ -} +#endif PHP_MINIT_FUNCTION(tidy) { + REGISTER_INI_ENTRIES(); #ifdef ZEND_ENGINE_2 - zend_class_entry _tidy_entry; INIT_CLASS_ENTRY(_tidy_entry, "TidyObject", NULL); php_tidy_ce = zend_register_internal_class(&_tidy_entry TSRMLS_CC); - #endif - ZEND_INIT_MODULE_GLOBALS(tidy, php_tidy_init_globals, NULL); - le_tidydoc = zend_register_list_destructors_ex(dtor_TidyDoc, NULL, le_tidydoc_name, module_number); - _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_attributes(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU); - - tidySetMallocCall(_php_tidy_mem_alloc); - tidySetReallocCall(_php_tidy_mem_realloc); - tidySetFreeCall(_php_tidy_mem_free); - tidySetPanicCall(_php_tidy_mem_panic); - - return SUCCESS; -} + ZEND_INIT_MODULE_GLOBALS(tidy, tidy_globals_ctor, tidy_globals_dtor); + return SUCCESS; +} PHP_MSHUTDOWN_FUNCTION(tidy) { - return SUCCESS; +#ifndef ZTS + tidy_globals_dtor(&tidy_globals TSRMLS_CC); +#endif + return SUCCESS; } - +PHP_RINIT_FUNCTION(tidy) +{ + if (TG(used) && tidyOptDiffThanSnapshot((tidy_globals.tdoc)->doc)) { + tidyOptResetToSnapshot((tidy_globals.tdoc)->doc); + TG(used) = 0; + } + /* if a user provided a default configuration file, use it */ + if (tidy_globals.default_config && tidy_globals.default_config[0]) { + if (tidyLoadConfig((tidy_globals.tdoc)->doc, tidy_globals.default_config) < 0) { + zend_error(E_ERROR, "Unable to load Tidy configuration file at '%s'.", tidy_globals.default_config); + } + TG(used) = 1; + } + return SUCCESS; +} PHP_MINFO_FUNCTION(tidy) { - + TidyIterator itOpt = tidyGetOptionList(TG(tdoc)->doc); + void *opt_value; + TidyOptionType optt; + char buf[255]; + php_info_print_table_start(); php_info_print_table_header(2, "Tidy support", "enabled"); - php_info_print_table_row(2, "Tidy Build Date", (char *)tidyReleaseDate()); + php_info_print_table_row(2, "libTidy Build Date", (char *)tidyReleaseDate()); php_info_print_table_end(); -} + DISPLAY_INI_ENTRIES(); -/* {{{ proto resource tidy_create() - Initialize a new tidy document */ -PHP_FUNCTION(tidy_create) -{ - - PHPTidyDoc *tdoc; - tdoc = emalloc(sizeof(PHPTidyDoc)); - tdoc->doc = tidyCreate(); - tdoc->parsed = 0; - - tdoc->errbuf = emalloc(sizeof(TidyBuffer)); - tidyBufInit(tdoc->errbuf); - - if(tidySetErrorBuffer(tdoc->doc, tdoc->errbuf) != 0) - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer"); - - tidyOptSetBool(tdoc->doc, TidyForceOutput, yes); - tidyOptSetBool(tdoc->doc, TidyMark, no); - - ZEND_REGISTER_RESOURCE(return_value, tdoc, le_tidydoc); - + php_info_print_table_start(); + php_info_print_table_header(2, "Tidy Configuration Directive", "Value"); + while (itOpt) { + TidyOption opt = tidyGetNextOption(TG(tdoc)->doc, &itOpt); + + opt_value = _php_tidy_get_opt_val(opt, &optt); + switch (optt) { + case TidyString: + php_info_print_table_row(2, (char *)tidyOptGetName(opt), (char*)opt_value); + efree(opt_value); + break; + + case TidyInteger: + sprintf(buf, "%d", (int)opt_value); + php_info_print_table_row(2, (char *)tidyOptGetName(opt), (char*)buf); + break; + + case TidyBoolean: + php_info_print_table_row(2, (char *)tidyOptGetName(opt), (opt_value ? "TRUE" : "FALSE")); + break; + } + } + php_info_print_table_end(); } -/* }}} */ -/* {{{ proto void tidy_parse_string(resource tidy, string input) +/* {{{ proto bool tidy_parse_string(string input) Parse a document stored in a string */ PHP_FUNCTION(tidy_parse_string) { - char *input; int input_len; - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &input, &input_len) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &input, &input_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(tidyParseString(tdoc->doc, input) < 0) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "[Tidy error] %s", tdoc->errbuf->bp); + + if(tidyParseString(TG(tdoc)->doc, input) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", TG(tdoc)->errbuf->bp); + RETURN_FALSE; } - - tdoc->parsed = 1; - + + TG(tdoc)->parsed = TRUE; + RETURN_TRUE; } /* }}} */ -/* {{{ proto string tidy_get_error_buffer(resource tidy [, boolean detailed]) +/* {{{ proto string tidy_get_error_buffer([boolean detailed]) Return warnings and errors which occured parsing the specified document*/ PHP_FUNCTION(tidy_get_error_buffer) { + zend_bool detailed = 0; - zval *res; - PHPTidyDoc *tdoc; - zend_bool detailed; - - if((ZEND_NUM_ARGS() == 0) || (ZEND_NUM_ARGS() > 2)) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r|b", &res, &detailed) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &detailed) == FAILURE) { + RETURN_FALSE; } - - if(detailed) { - tidyErrorSummary(tdoc->doc); + + TIDY_PARSED_CHECK(); + + if (detailed) { + tidyErrorSummary(TG(tdoc)->doc); } - - RETVAL_STRING(tdoc->errbuf->bp, 1); - - tidyBufClear(tdoc->errbuf); - + + RETVAL_STRING(TG(tdoc)->errbuf->bp, 1); + tidyBufClear(TG(tdoc)->errbuf); } /* }}} */ -/* {{{ proto string tidy_get_output(resource tidy) +/* {{{ proto string tidy_get_output() Return a string representing the parsed tidy markup */ PHP_FUNCTION(tidy_get_output) { - - zval *res; - PHPTidyDoc *tdoc; TidyBuffer output = {0}; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + + if (ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - tidySaveBuffer( tdoc->doc, &output ); - + + TIDY_PARSED_CHECK(); + + tidySaveBuffer (TG(tdoc)->doc, &output); + RETVAL_STRING(output.bp, 1); - + tidyBufFree(&output); - } /* }}} */ -/* {{{ proto boolean tidy_parse_file(resource tidy, string file) +/* {{{ proto boolean tidy_parse_file(string file) Parse markup in file or URI */ PHP_FUNCTION(tidy_parse_file) { - char *inputfile; int input_len; - zval *res; - PHPTidyDoc *tdoc; php_stream *stream; char *contents; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &inputfile, &input_len) == FAILURE) { + RETURN_FALSE; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &inputfile, &input_len) == FAILURE) { - return; + + if (!(stream = php_stream_open_wrapper(inputfile, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL))) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - stream = php_stream_open_wrapper(inputfile, "rb", - ENFORCE_SAFE_MODE | REPORT_ERRORS, - NULL); - - if(!stream) { - RETURN_FALSE; + + if (php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0) > 0) { + if(tidyParseString(TG(tdoc)->doc, contents) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", TG(tdoc)->errbuf->bp); + efree(contents); + php_stream_close(stream); + RETURN_FALSE; + } + TG(tdoc)->parsed = TRUE; + efree(contents); } - - if (php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0) > 0) { - - if(tidyParseString(tdoc->doc, contents) < 0) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "[Tidy error] %s", tdoc->errbuf->bp); - } - tdoc->parsed = TRUE; - efree(contents); - } - - php_stream_close(stream); - + php_stream_close(stream); + RETURN_TRUE; } /* }}} */ -/* {{{ proto boolean tidy_clean_repair(resource tidy) +/* {{{ proto boolean tidy_clean_repair() Execute configured cleanup and repair operations on parsed markup */ PHP_FUNCTION(tidy_clean_repair) { - - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + + TIDY_PARSED_CHECK(); + + if (tidyCleanAndRepair(TG(tdoc)->doc) >= 0) { + RETURN_TRUE; } - - if(tidyCleanAndRepair(tdoc->doc) >= 0) RETURN_TRUE; - + RETURN_FALSE; - } /* }}} */ -/* {{{ proto boolean tidy_diagnose(resource tidy) +/* {{{ proto boolean tidy_diagnose() Run configured diagnostics on parsed and repaired markup. */ PHP_FUNCTION(tidy_diagnose) { - - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + + TIDY_PARSED_CHECK(); + + if (tidyRunDiagnostics(TG(tdoc)->doc) >= 0) { + RETURN_TRUE; } - - if(tidyRunDiagnostics(tdoc->doc) >= 0) RETURN_TRUE; - + RETURN_FALSE; } @@ -608,576 +568,428 @@ PHP_FUNCTION(tidy_diagnose) Get release date (version) for Tidy library */ PHP_FUNCTION(tidy_get_release) { + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } RETURN_STRING((char *)tidyReleaseDate(), 1); } /* }}} */ -/* {{{ proto int tidy_get_status(resource tidy) +/* {{{ proto string tidy_reset_config() + Restore Tidy configuration to default values */ +PHP_FUNCTION(tidy_reset_config) +{ + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + RETURN_BOOL(tidyOptResetToSnapshot(TG(tdoc)->doc)); +} +/* }}} */ + +/* {{{ proto array tidy_get_config() + Get current Tidy configuarion */ +PHP_FUNCTION(tidy_get_config) +{ + TidyIterator itOpt = tidyGetOptionList(TG(tdoc)->doc); + char *opt_name; + void *opt_value; + TidyOptionType optt; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + array_init(return_value); + + while (itOpt) { + TidyOption opt = tidyGetNextOption(TG(tdoc)->doc, &itOpt); + + opt_name = (char *)tidyOptGetName(opt); + opt_value = _php_tidy_get_opt_val(opt, &optt); + switch (optt) { + case TidyString: + add_assoc_string(return_value, opt_name, (char*)opt_value, 0); + break; + + case TidyInteger: + add_assoc_long(return_value, opt_name, (long)opt_value); + break; + + case TidyBoolean: + add_assoc_bool(return_value, opt_name, (long)opt_value); + break; + } + } + + return; +} +/* }}} */ + + +/* {{{ proto int tidy_get_status() Get status of specfied document. */ PHP_FUNCTION(tidy_get_status) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - RETURN_LONG(tidyStatus(tdoc->doc)); - + + RETURN_LONG(tidyStatus(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto int tidy_get_html_ver(resource tidy) +/* {{{ proto int tidy_get_html_ver() Get the Detected HTML version for the specified document. */ PHP_FUNCTION(tidy_get_html_ver) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - - RETURN_LONG(tidyDetectedHtmlVersion(tdoc->doc)); + + TIDY_PARSED_CHECK(); + + RETURN_LONG(tidyDetectedHtmlVersion(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto boolean tidy_is_xhtml(resource tidy) +/* {{{ proto boolean tidy_is_xhtml() Indicates if the document is a XHTML document. */ PHP_FUNCTION(tidy_is_xhtml) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - - RETURN_BOOL(tidyDetectedXhtml(tdoc->doc)); - + + TIDY_PARSED_CHECK(); + + RETURN_BOOL(tidyDetectedXhtml(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto boolean tidy_is_xhtml(resource tidy) +/* {{{ proto boolean tidy_is_xhtml() Indicates if the document is a generic (non HTML/XHTML) XML document. */ PHP_FUNCTION(tidy_is_xml) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - - RETURN_BOOL(tidyDetectedGenericXml(tdoc->doc)); + + TIDY_PARSED_CHECK(); + + RETURN_BOOL(tidyDetectedGenericXml(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto int tidy_error_count(resource tidy) +/* {{{ proto int tidy_error_count() Returns the Number of Tidy errors encountered for specified document. */ PHP_FUNCTION(tidy_error_count) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - RETURN_LONG(tidyErrorCount(tdoc->doc)); + + TIDY_PARSED_CHECK(); + + RETURN_LONG(tidyErrorCount(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto int tidy_warning_count(resource tidy) +/* {{{ proto int tidy_warning_count() Returns the Number of Tidy warnings encountered for specified document. */ PHP_FUNCTION(tidy_warning_count) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - - RETURN_LONG(tidyWarningCount(tdoc->doc)); + + TIDY_PARSED_CHECK(); + + RETURN_LONG(tidyWarningCount(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto int tidy_access_count(resource tidy) +/* {{{ proto int tidy_access_count() Returns the Number of Tidy accessibility warnings encountered for specified document. */ PHP_FUNCTION(tidy_access_count) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - - RETURN_LONG(tidyAccessWarningCount(tdoc->doc)); - + + TIDY_PARSED_CHECK(); + + RETURN_LONG(tidyAccessWarningCount(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto int tidy_config_count(resource tidy) +/* {{{ proto int tidy_config_count() Returns the Number of Tidy configuration errors encountered for specified document. */ PHP_FUNCTION(tidy_config_count) { - zval *res; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - - RETURN_LONG(tidyConfigErrorCount(tdoc->doc)); - + + TIDY_PARSED_CHECK(); + + RETURN_LONG(tidyConfigErrorCount(TG(tdoc)->doc)); } /* }}} */ -/* {{{ proto void tidy_load_config(resource tidy, string filename) +/* {{{ proto void tidy_load_config(string filename) Load an ASCII Tidy configuration file */ PHP_FUNCTION(tidy_load_config) { - zval *res; char *filename; int filename_len; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &filename, &filename_len) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - if(tidyLoadConfig(tdoc->doc, filename) < 0) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not load configuration file '%s'", filename); + + TIDY_SAFE_MODE_CHECK(filename); + + if(tidyLoadConfig(TG(tdoc)->doc, filename) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", filename); + RETURN_FALSE; } - + + RETURN_TRUE; } /* }}} */ -/* {{{ proto void tidy_load_config(resource tidy, string filename, string encoding) +/* {{{ proto void tidy_load_config(string filename, string encoding) Load an ASCII Tidy configuration file with the specified encoding */ PHP_FUNCTION(tidy_load_config_enc) { - zval *res; - char *filename; - char *encoding; + char *filename, *encoding; int enc_len, file_len; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rss", &res, &filename, &file_len, &encoding, &enc_len) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &filename, &file_len, &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - if(tidyLoadConfigEnc(tdoc->doc, filename, encoding) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s' using encoding '%s'", filename, encoding); - RETURN_FALSE; + + TIDY_SAFE_MODE_CHECK(filename); + + if(tidyLoadConfigEnc(TG(tdoc)->doc, filename, encoding) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s' using encoding '%s'", filename, encoding); + RETURN_FALSE; } - + RETURN_TRUE; } /* }}} */ -/* {{{ proto boolean tidy_set_encoding(resource tidy, string encoding) +/* {{{ proto boolean tidy_set_encoding(string encoding) Set the input/output character encoding for parsing markup. Values include: ascii, latin1, raw, utf8, iso2022, mac, win1252, utf16le, utf16be, utf16, big5 and shiftjis. */ PHP_FUNCTION(tidy_set_encoding) { - zval *res; char *encoding; int enc_len; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &encoding, &enc_len) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - if(tidySetCharEncoding(tdoc->doc, encoding) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", encoding); - RETURN_FALSE; + + if(tidySetCharEncoding(TG(tdoc)->doc, encoding) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", encoding); + RETURN_FALSE; } - + RETURN_TRUE; } /* }}} */ -/* {{{ proto boolean tidy_save_config(resource tidy, string filename) +/* {{{ proto boolean tidy_save_config(string filename) Save current settings to named file. Only non-default values are written. */ PHP_FUNCTION(tidy_save_config) { - zval *res; char *filename; int file_len; - PHPTidyDoc *tdoc; - - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &filename, &file_len) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &file_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - if(tidyOptSaveFile(tdoc->doc, filename) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not write tidy configuration file '%s'", filename); - RETURN_FALSE; + + TIDY_SAFE_MODE_CHECK(filename); + + if(tidyOptSaveFile(TG(tdoc)->doc, filename) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not write tidy configuration file '%s'", filename); + RETURN_FALSE; } - + RETURN_TRUE; } /* }}} */ -/* {{{ proto boolean tidy_setopt(resource tidy, string option, mixed newvalue) +/* {{{ proto boolean tidy_setopt(string option, mixed newvalue) Updates the configuration settings for the specified tidy document. */ PHP_FUNCTION(tidy_setopt) { - - zval *res, *value; + zval *value; char *optname; int optname_len; - PHPTidyDoc *tdoc; TidyOption opt; - - - if(ZEND_NUM_ARGS() != 3) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rsz", &res, &optname, &optname_len, &value) == FAILURE) { - return; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &optname, &optname_len, &value) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->doc) { - php_error_docref(NULL TSRMLS_CC,E_ERROR, "Invalid Tidy Resource Specified"); - RETURN_FALSE; + + opt = tidyGetOptionByName(TG(tdoc)->doc, optname); + if (!opt) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); + RETURN_FALSE; } - - opt = tidyGetOptionByName(tdoc->doc, optname); - if(!opt) { - php_error_docref(NULL TSRMLS_CC,E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); - RETURN_FALSE; - } switch(tidyOptGetType(opt)) { - case TidyString: - if(tidyOptSetValue(tdoc->doc, tidyOptGetId(opt), Z_STRVAL_P(value))) { + convert_to_string_ex(&value); + if(tidyOptSetValue(TG(tdoc)->doc, tidyOptGetId(opt), Z_STRVAL_P(value))) { + TG(used) = 1; RETURN_TRUE; } break; case TidyInteger: - if(tidyOptSetInt(tdoc->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { + convert_to_long_ex(&value); + if(tidyOptSetInt(TG(tdoc)->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { + TG(used) = 1; RETURN_TRUE; } break; case TidyBoolean: - if(tidyOptSetBool(tdoc->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { + convert_to_long_ex(&value); + if(tidyOptSetBool(TG(tdoc)->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { + TG(used) = 1; RETURN_TRUE; } break; default: - - php_error_docref(NULL TSRMLS_CC,E_WARNING, "Unable to determine type of Tidy configuration constant to set"); - + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to set"); + break; } RETURN_FALSE; } /* }}} */ -/* {{{ proto mixed tidy_getopt(resource tidy, string option) +/* {{{ proto mixed tidy_getopt(string option) Returns the value of the specified configuration option for the tidy document. */ PHP_FUNCTION(tidy_getopt) { - - zval *res; - char *optname, *strval; + char *optname; + void *optval; int optname_len; - PHPTidyDoc *tdoc; - TidyOption opt; + TidyOption opt; + TidyOptionType optt; - if(ZEND_NUM_ARGS() != 2) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "rs", &res, &optname, &optname_len) == FAILURE) { - return; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) { + RETURN_FALSE; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->doc) { - php_error_docref(NULL TSRMLS_CC,E_ERROR, "Invalid Tidy Resource Specified"); - RETURN_FALSE; + + opt = tidyGetOptionByName(TG(tdoc)->doc, optname); + if (!opt) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); + RETURN_FALSE; } - - opt = tidyGetOptionByName(tdoc->doc, optname); - if(!opt) { - php_error_docref(NULL TSRMLS_CC,E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); - RETURN_FALSE; - } - switch(tidyOptGetType(opt)) { - - case TidyString: - strval = (char *)tidyOptGetValue(tdoc->doc, tidyOptGetId(opt)); - - if(strval) { - RETURN_STRING(strval, 0); - } else { - RETURN_EMPTY_STRING(); - } - - break; - case TidyInteger: - RETURN_LONG(tidyOptGetInt(tdoc->doc, tidyOptGetId(opt))) - break; - case TidyBoolean: - - if(tidyOptGetBool(tdoc->doc, tidyOptGetId(opt))) { - RETURN_TRUE; - } - - break; - - default: - - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to get"); + optval = _php_tidy_get_opt_val(opt, &optt); + switch (optt) { + case TidyString: + RETVAL_STRING((char *)optval, 0); + break; + + case TidyInteger: + RETURN_LONG((long)optval); + break; + + case TidyBoolean: + if (optval) { + RETURN_TRUE; + } else { + RETURN_NULL(); + } + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to get"); + break; } - + RETURN_FALSE; - } /* }}} */ #ifdef ZEND_ENGINE_2 -/* {{{ proto TidyNode tidy_get_root(resource tidy) +/* {{{ proto TidyNode tidy_get_root() Returns a TidyNode Object representing the root of the tidy parse tree */ PHP_FUNCTION(tidy_get_root) { + PHPTidyObj *obj; - zval *res; - PHPTidyDoc *tdoc; - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - + + TIDY_PARSED_CHECK(); + obj = php_tidy_new(); - obj->node = tidyGetRoot(tdoc->doc); - obj->tdoc = tdoc; + obj->node = tidyGetRoot(TG(tdoc)->doc); obj->attr = NULL; obj->type = PHP_IS_TIDYNODE; - + return_value->type = IS_OBJECT; return_value->value.obj = php_tidy_register_object(obj TSRMLS_CC); - } /* }}} */ -/* {{{ proto TidyNode tidy_get_html(resource tidy) +/* {{{ proto TidyNode tidy_get_html() Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_html) { - - zval *res; - PHPTidyDoc *tdoc; - PHPTidyObj *obj; + PHPTidyObj *obj; - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - + + TIDY_PARSED_CHECK(); + obj = php_tidy_new(); - obj->node = tidyGetHtml(tdoc->doc); - obj->tdoc = tdoc; + obj->node = tidyGetHtml(TG(tdoc)->doc); obj->attr = NULL; obj->type = PHP_IS_TIDYNODE; - + return_value->type = IS_OBJECT; return_value->value.obj = php_tidy_register_object(obj TSRMLS_CC); - } /* }}} */ -/* {{{ proto TidyNode tidy_get_head(resource tidy) +/* {{{ proto TidyNode tidy_get_head() Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_head) { + PHPTidyObj *obj; - zval *res; - PHPTidyDoc *tdoc; - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - + + TIDY_PARSED_CHECK(); + obj = php_tidy_new(); - obj->node = tidyGetHead(tdoc->doc); - obj->tdoc = tdoc; + obj->node = tidyGetHead(TG(tdoc)->doc); obj->attr = NULL; obj->type = PHP_IS_TIDYNODE; - + return_value->type = IS_OBJECT; return_value->value.obj = php_tidy_register_object(obj TSRMLS_CC); - } /* }}} */ @@ -1185,36 +997,21 @@ PHP_FUNCTION(tidy_get_head) Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_body) { - - zval *res; - PHPTidyDoc *tdoc; PHPTidyObj *obj; - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "r", &res) == FAILURE) { - return; - } - - ZEND_FETCH_RESOURCE(tdoc, PHPTidyDoc *, &res, -1, le_tidydoc_name, le_tidydoc); - if(!tdoc->parsed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); - RETURN_FALSE; - } - - obj = php_tidy_new(); - obj->node = tidyGetBody(tdoc->doc); - obj->tdoc = tdoc; - obj->attr = NULL; - obj->type = PHP_IS_TIDYNODE; + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + TIDY_PARSED_CHECK(); + + obj = php_tidy_new(); + obj->node = tidyGetBody(TG(tdoc)->doc); + obj->attr = NULL; + obj->type = PHP_IS_TIDYNODE; - return_value->type = IS_OBJECT; + return_value->type = IS_OBJECT; return_value->value.obj = php_tidy_register_object(obj TSRMLS_CC); - } /* }}} */ @@ -1231,127 +1028,104 @@ union _zend_function * tidy_get_constructor(zval *obj TSRMLS_DC) zval *tidy_read_dim(zval *object, zval *offset TSRMLS_DC) { - return EG(uninitialized_zval_ptr); } zend_class_entry * tidy_get_class_entry(zval *obj TSRMLS_DC) { - return php_tidy_ce; } - zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC) { zval **p_ptr = NULL; zval *p; - + p = tidy_property_read(obj, member, 0 TSRMLS_CC); *p_ptr = p; - + return p_ptr; - } zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC) { - PHPTidyObj *obj = php_tidy_fetch_object(object TSRMLS_CC); zval *return_value, *temp; TidyBuffer buf; TidyNode tempnode; TidyAttr tempattr; char *temp_str; - + char *name = Z_STRVAL_P(member); - + MAKE_STD_ZVAL(return_value); ZVAL_NULL(return_value); /* Seems to me the engine expects to simply recieve a pointer to - an already-existing zval, not for one to be created and returned.. - - Thus, it doesn't feel compelled to free the return value once it's - done with it... this seems to compell it appropiately. */ + * an already-existing zval, not for one to be created and returned.. + * Thus, it doesn't feel compelled to free the return value once it's + * done with it... this seems to compell it appropiately. + */ return_value->refcount--; - + switch(obj->type) { - case PHP_IS_TIDYNODE: - if(!strcmp(name, "name")) { temp_str = (char *)tidyNodeGetName(obj->node); if(temp_str) { ZVAL_STRING(return_value, temp_str, 1); } - } else if(!strcmp(name, "value")) { - memset(&buf, 0, sizeof(buf)); - tidyNodeGetText(obj->tdoc->doc, obj->node, &buf); + tidyNodeGetText(TG(tdoc)->doc, obj->node, &buf); ZVAL_STRING(return_value, (char *)buf.bp, 1); - + /* The buffer adds a newline at the end of the string */ REMOVE_NEWLINE(return_value); - + tidyBufFree(&buf); - } else if(!strcmp(name, "type")) { - ZVAL_LONG(return_value, tidyNodeGetType(obj->node)); } else if(!strcmp(name, "id")) { - if(tidyNodeGetName(obj->node)) { ZVAL_LONG(return_value, tidyNodeGetId(obj->node)); } - } else if(!strcmp(name, "attribs")) { - array_init(return_value); - + tempattr = tidyAttrFirst(obj->node); - + if(tempattr) { - temp = _php_tidy_create_obj_zval(PHP_IS_TIDYATTR, obj, tempattr TSRMLS_CC); add_next_index_zval(return_value, temp); while((tempattr = tidyAttrNext(tempattr))) { - temp = _php_tidy_create_obj_zval(PHP_IS_TIDYATTR, obj, tempattr TSRMLS_CC); add_next_index_zval(return_value, temp); } } - } else if(!strcmp(name, "children")) { - array_init(return_value); tempnode = tidyGetChild(obj->node); if(tempnode) { - temp = _php_tidy_create_obj_zval(PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); add_next_index_zval(return_value, temp); while((tempnode = tidyGetNext(tempnode))) { - temp = _php_tidy_create_obj_zval(PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); add_next_index_zval(return_value, temp); } } - } else if(!strcmp(name, "line")) { ZVAL_LONG(return_value, tidyNodeLine(obj->node)); } else if(!strcmp(name, "column")) { ZVAL_LONG(return_value, tidyNodeColumn(obj->node)); } else if(!strcmp(name, "html_ver")) { - ZVAL_LONG(return_value, tidyDetectedHtmlVersion(obj->tdoc->doc)); + ZVAL_LONG(return_value, tidyDetectedHtmlVersion(TG(tdoc)->doc)); } - break; - + case PHP_IS_TIDYATTR: - if(!strcmp(name, "name")) { temp_str = (char *)tidyAttrName(obj->attr); if(temp_str) { @@ -1366,35 +1140,30 @@ zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC } else if(!strcmp(name, "id")) { ZVAL_LONG(return_value, tidyAttrGetId(obj->attr)); } - break; + default: - php_error_docref(NULL TSRMLS_CC,E_ERROR, "Undefined Tidy object type."); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined Tidy object type."); break; } - + return return_value; - } int tidy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC) { - return TRUE; } HashTable * tidy_get_properties(zval *object TSRMLS_DC) { - zend_object *zobj; zobj = zend_objects_get_address(object TSRMLS_CC); return zobj->properties; - } union _zend_function * tidy_get_method(zval *obj, char *method, int method_len TSRMLS_DC) { - zend_internal_function *f; f = emalloc(sizeof(zend_internal_function)); @@ -1409,72 +1178,55 @@ union _zend_function * tidy_get_method(zval *obj, char *method, int method_len T zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) { - PHPTidyObj *obj = php_tidy_fetch_object(getThis() TSRMLS_CC); zend_internal_function *func = (zend_internal_function *)EG(function_state_ptr)->function; PHPTidyObj *newobj; TidyNode tempnode; TidyAttr tempattr; zend_bool retval = TRUE; - + int param; - + if(strstr(method, "has_")) { - if(!strcmp(method, "has_siblings")) { - if(tidyGetNext(obj->node) || tidyGetPrev(obj->node)) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "has_children")) { - if(tidyGetChild(obj->node)) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "has_parent")) { - if(tidyGetParent(obj->node)) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } - } else if(strstr(method, "is_")) { - if(!strcmp(method, "is_comment")) { - if(tidyNodeGetType(obj->node) == TidyNode_Comment) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_xhtml")) { - - if(tidyDetectedXhtml(obj->tdoc->doc)) { + if(tidyDetectedXhtml(TG(tdoc)->doc)) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_xml")) { - - if(tidyDetectedGenericXml(obj->tdoc->doc)) { + if(tidyDetectedGenericXml(TG(tdoc)->doc)) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_text")) { - if(tidyNodeGetType(obj->node) == TidyNode_Text) { TIDY_RV_TRUE(return_value); } else { @@ -1482,33 +1234,25 @@ zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) } } else if(!strcmp(method, "is_jste")) { - if(tidyNodeGetType(obj->node) == TidyNode_Jste) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_asp")) { - if(tidyNodeGetType(obj->node) == TidyNode_Asp) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_php")) { - if(tidyNodeGetType(obj->node) == TidyNode_Php) { TIDY_RV_TRUE(return_value); } else { TIDY_RV_FALSE(return_value); } - } else if(!strcmp(method, "is_html")) { - switch(tidyNodeGetType(obj->node)) { - case TidyNode_Start: case TidyNode_End: case TidyNode_StartEnd: @@ -1518,193 +1262,137 @@ zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) TIDY_RV_FALSE(return_value); break; } - } - } else { - if(!strcmp(method, "next")) { - - tempnode = tidyGetNext(obj->node); - if(tempnode) { - _php_tidy_create_obj(return_value, - PHP_IS_TIDYNODE, - obj, - tempnode TSRMLS_CC); - } - + tempnode = tidyGetNext(obj->node); + if(tempnode) { + _php_tidy_create_obj(return_value, PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); + } } else if(!strcmp(method, "prev")) { - - tempnode = tidyGetPrev(obj->node); - if(tempnode) { - _php_tidy_create_obj(return_value, - PHP_IS_TIDYNODE, - obj, - tempnode TSRMLS_CC); - } - + tempnode = tidyGetPrev(obj->node); + if(tempnode) { + _php_tidy_create_obj(return_value, PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); + } } else if(!strcmp(method, "parent")) { - - tempnode = tidyGetParent(obj->node); - if(tempnode) { - _php_tidy_create_obj(return_value, - PHP_IS_TIDYNODE, - obj, - tempnode TSRMLS_CC); - } - + tempnode = tidyGetParent(obj->node); + if(tempnode) { + _php_tidy_create_obj(return_value, PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); + } } else if(!strcmp(method, "child")) { - - tempnode = tidyGetChild(obj->node); - if(tempnode) { - _php_tidy_create_obj(return_value, - PHP_IS_TIDYNODE, - obj, - tempnode TSRMLS_CC); - } - + tempnode = tidyGetChild(obj->node); + if(tempnode) { + _php_tidy_create_obj(return_value, PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC); + } } else if(!strcmp(method, "get_attr_type")) { - - if(ZEND_NUM_ARGS() != 1) { - zend_wrong_param_count(TSRMLS_C); - return TRUE; - } - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "l", ¶m) == FAILURE) { + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", ¶m) == FAILURE) { return FALSE; } - - newobj = php_tidy_new(); - newobj->tdoc = obj->tdoc; - + for(tempattr = tidyAttrFirst(obj->node); tempattr; tempattr = tidyAttrNext(tempattr)) { - + if(tidyAttrGetId(tempattr) == param) { - newobj->attr = tempattr; newobj->type = PHP_IS_TIDYATTR; obj->refcount++; - + return_value->type = IS_OBJECT; return_value->value.obj = php_tidy_register_object(newobj TSRMLS_CC); - + break; - } - } - } else { retval = FALSE; - } } + efree(func->function_name); efree(func); return retval; - } zend_bool _php_tidy_attr_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) { - PHPTidyObj *obj = php_tidy_fetch_object(getThis() TSRMLS_CC); TidyAttr tempattr; - + if(!strcmp(method, "next")) { - tempattr = tidyAttrNext(obj->attr); - if(tempattr) { _php_tidy_create_obj(return_value, PHP_IS_TIDYATTR, obj, tempattr TSRMLS_CC); } else { - TIDY_RV_FALSE(return_value); - } - } else if(!strcmp(method, "tag")) { _php_tidy_create_obj(return_value, PHP_IS_TIDYNODE, obj, obj->node TSRMLS_CC); } else { return FALSE; } - + return TRUE; } int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) { - PHPTidyObj *obj = php_tidy_fetch_object(getThis() TSRMLS_CC); switch(obj->type) { - case PHP_IS_TIDYNODE: return _php_tidy_node_call_method(method, INTERNAL_FUNCTION_PARAM_PASSTHRU); break; + case PHP_IS_TIDYATTR: return _php_tidy_attr_call_method(method, INTERNAL_FUNCTION_PARAM_PASSTHRU); break; + default: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Undefined Tidy object type."); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined Tidy object type."); break; } - + return FALSE; } int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len, int parent TSRMLS_DC) { - PHPTidyObj *object = php_tidy_fetch_object(obj TSRMLS_CC); - + switch(object->type) { - case PHP_IS_TIDYNODE: - *class_name = estrdup("Tidy_Node"); *name_len = sizeof("Tidy_Node"); - break; + case PHP_IS_TIDYATTR: - *class_name = estrdup("Tidy_Attribute"); *name_len = sizeof("Tidy_Attribute"); - break; + default: - *class_name = estrdup("Tidy_Unknown"); *name_len = sizeof("Tidy_Unknown"); break; } - + return TRUE; } int tidy_objects_compare(zval *obj_one, zval *obj_two TSRMLS_DC) { - PHPTidyObj *obj1, *obj2; - + obj1 = php_tidy_fetch_object(obj_one TSRMLS_CC); obj2 = php_tidy_fetch_object(obj_two TSRMLS_CC); - - if( (obj1->tdoc == obj2->tdoc) && - (obj1->node == obj2->node) && - (obj1->attr == obj2->attr) && - (obj1->type == obj2->type)) { - + + if (((obj1->node == obj2->node) && (obj1->attr == obj2->attr) && (obj1->type == obj2->type)) { return TRUE; - } - + return FALSE; - } #endif -- 2.40.0