]> granicus.if.org Git - php/commitdiff
Refactored tidy (all tests passes)
authorXinchen Hui <laruence@php.net>
Wed, 14 May 2014 08:44:07 +0000 (16:44 +0800)
committerXinchen Hui <laruence@php.net>
Wed, 14 May 2014 08:44:07 +0000 (16:44 +0800)
ext/tidy/tests/010.phpt
ext/tidy/tests/012.phpt
ext/tidy/tidy.c

index 9d5ab825a0bd0db8c490c650edf0081ca0742284..85d9df519020f107d9ecd286efc69885c589048a 100644 (file)
@@ -36,7 +36,7 @@ object(tidyNode)#2 (8) {
   ["child"]=>
   array(1) {
     [0]=>
-    &object(tidyNode)#3 (9) {
+    object(tidyNode)#3 (9) {
       ["value"]=>
       string(94) "<html>
 <head>
@@ -62,7 +62,7 @@ object(tidyNode)#2 (8) {
       ["child"]=>
       array(2) {
         [0]=>
-        &object(tidyNode)#4 (9) {
+        object(tidyNode)#4 (9) {
           ["value"]=>
           string(31) "<head>
 <title></title>
@@ -85,7 +85,7 @@ object(tidyNode)#2 (8) {
           ["child"]=>
           array(1) {
             [0]=>
-            &object(tidyNode)#5 (9) {
+            object(tidyNode)#5 (9) {
               ["value"]=>
               string(16) "<title></title>
 "
@@ -109,7 +109,7 @@ object(tidyNode)#2 (8) {
           }
         }
         [1]=>
-        &object(tidyNode)#6 (9) {
+        object(tidyNode)#6 (9) {
           ["value"]=>
           string(49) "<body bgcolor="#FFFFFF" alink="#000000">
 </body>
@@ -193,7 +193,7 @@ object(tidyNode)#2 (9) {
   ["child"]=>
   array(2) {
     [0]=>
-    &object(tidyNode)#3 (9) {
+    object(tidyNode)#3 (9) {
       ["value"]=>
       string(31) "<head>
 <title></title>
@@ -216,7 +216,7 @@ object(tidyNode)#2 (9) {
       ["child"]=>
       array(1) {
         [0]=>
-        &object(tidyNode)#6 (9) {
+        object(tidyNode)#6 (9) {
           ["value"]=>
           string(16) "<title></title>
 "
@@ -240,7 +240,7 @@ object(tidyNode)#2 (9) {
       }
     }
     [1]=>
-    &object(tidyNode)#4 (9) {
+    object(tidyNode)#4 (9) {
       ["value"]=>
       string(49) "<body bgcolor="#FFFFFF" alink="#000000">
 </body>
@@ -292,7 +292,7 @@ object(tidyNode)#2 (9) {
   ["child"]=>
   array(1) {
     [0]=>
-    &object(tidyNode)#4 (9) {
+    object(tidyNode)#4 (9) {
       ["value"]=>
       string(16) "<title></title>
 "
index 1205812333e8902fa25a7b91911af391a733c06f..39ce22bec16720f6a62844355a1849be1c2c523d 100644 (file)
@@ -55,7 +55,7 @@ object(tidyNode)#3 (9) {
   ["child"]=>
   array(1) {
     [0]=>
-    &object(tidyNode)#4 (9) {
+    object(tidyNode)#4 (9) {
       ["value"]=>
       string(16) "<title></title>
 "
@@ -128,7 +128,7 @@ object(tidyNode)#5 (9) {
   ["child"]=>
   array(2) {
     [0]=>
-    &object(tidyNode)#6 (9) {
+    object(tidyNode)#6 (9) {
       ["value"]=>
       string(9) "<b>Hi</b>"
       ["name"]=>
@@ -148,7 +148,7 @@ object(tidyNode)#5 (9) {
       ["child"]=>
       array(1) {
         [0]=>
-        &object(tidyNode)#7 (8) {
+        object(tidyNode)#7 (8) {
           ["value"]=>
           string(2) "Hi"
           ["name"]=>
@@ -169,7 +169,7 @@ object(tidyNode)#5 (9) {
       }
     }
     [1]=>
-    &object(tidyNode)#8 (9) {
+    object(tidyNode)#8 (9) {
       ["value"]=>
       string(21) "<i>Bye<u>Test</u></i>"
       ["name"]=>
@@ -189,7 +189,7 @@ object(tidyNode)#5 (9) {
       ["child"]=>
       array(2) {
         [0]=>
-        &object(tidyNode)#9 (8) {
+        object(tidyNode)#9 (8) {
           ["value"]=>
           string(3) "Bye"
           ["name"]=>
@@ -208,7 +208,7 @@ object(tidyNode)#5 (9) {
           NULL
         }
         [1]=>
-        &object(tidyNode)#10 (9) {
+        object(tidyNode)#10 (9) {
           ["value"]=>
           string(11) "<u>Test</u>"
           ["name"]=>
@@ -228,7 +228,7 @@ object(tidyNode)#5 (9) {
           ["child"]=>
           array(1) {
             [0]=>
-            &object(tidyNode)#11 (8) {
+            object(tidyNode)#11 (8) {
               ["value"]=>
               string(4) "Test"
               ["name"]=>
@@ -273,7 +273,7 @@ object(tidyNode)#6 (9) {
   ["child"]=>
   array(1) {
     [0]=>
-    &object(tidyNode)#7 (8) {
+    object(tidyNode)#7 (8) {
       ["value"]=>
       string(2) "Hi"
       ["name"]=>
@@ -332,7 +332,7 @@ object(tidyNode)#8 (9) {
   ["child"]=>
   array(2) {
     [0]=>
-    &object(tidyNode)#9 (8) {
+    object(tidyNode)#9 (8) {
       ["value"]=>
       string(3) "Bye"
       ["name"]=>
@@ -351,7 +351,7 @@ object(tidyNode)#8 (9) {
       NULL
     }
     [1]=>
-    &object(tidyNode)#10 (9) {
+    object(tidyNode)#10 (9) {
       ["value"]=>
       string(11) "<u>Test</u>"
       ["name"]=>
@@ -371,7 +371,7 @@ object(tidyNode)#8 (9) {
       ["child"]=>
       array(1) {
         [0]=>
-        &object(tidyNode)#11 (8) {
+        object(tidyNode)#11 (8) {
           ["value"]=>
           string(4) "Test"
           ["name"]=>
@@ -432,7 +432,7 @@ object(tidyNode)#10 (9) {
   ["child"]=>
   array(1) {
     [0]=>
-    &object(tidyNode)#11 (8) {
+    object(tidyNode)#11 (8) {
       ["value"]=>
       string(4) "Test"
       ["name"]=>
index b2144676323724dc7d0d48cb93593ad42e6f48f3..c9f910753004c32771dd5d9f0402d71b0747dc19 100644 (file)
@@ -59,7 +59,7 @@
                        RETURN_FALSE;   \
                }       \
        }       \
-       obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);    \
+       obj = Z_TIDY_P(object); \
 
 #define TIDY_FETCH_ONLY_OBJECT \
        PHPTidyObj *obj;        \
        if (zend_parse_parameters_none() == FAILURE) {  \
                return; \
        }       \
-       obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);    \
+       obj = Z_TIDY_P(object); \
 
 #define TIDY_APPLY_CONFIG_ZVAL(_doc, _val) \
     if(_val) { \
-        if(Z_TYPE_PP(_val) == IS_ARRAY) { \
-            _php_tidy_apply_config_array(_doc, HASH_OF(*_val) TSRMLS_CC); \
+        if(Z_TYPE_P(_val) == IS_ARRAY) { \
+            _php_tidy_apply_config_array(_doc, HASH_OF(_val) TSRMLS_CC); \
         } else { \
             convert_to_string_ex(_val); \
-            TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_PP(_val)); \
-            switch (tidyLoadConfig(_doc, Z_STRVAL_PP(_val))) { \
+            TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_P(_val)); \
+            switch (tidyLoadConfig(_doc, Z_STRVAL_P(_val))) { \
               case -1: \
-                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_PP(_val)); \
+                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_P(_val)); \
                 break; \
               case 1: \
-                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_PP(_val)); \
+                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_P(_val)); \
                 break; \
             } \
         } \
 
 #define ADD_PROPERTY_STRING(_table, _key, _string) \
        { \
-               zval *tmp; \
-               MAKE_STD_ZVAL(tmp); \
+               zval tmp; \
                if (_string) { \
-                       ZVAL_STRING(tmp, (char *)_string, 1); \
+                       ZVAL_STRING(&tmp, (char *)_string); \
                } else { \
-                       ZVAL_EMPTY_STRING(tmp); \
+                       ZVAL_EMPTY_STRING(&tmp); \
                } \
-               zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
+               zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
        }
 
 #define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \
    { \
-       zval *tmp; \
-       MAKE_STD_ZVAL(tmp); \
+       zval tmp; \
        if (_string) { \
-           ZVAL_STRINGL(tmp, (char *)_string, _len, 1); \
+           ZVAL_STRINGL(&tmp, (char *)_string, _len); \
        } else { \
-           ZVAL_EMPTY_STRING(tmp); \
+           ZVAL_EMPTY_STRING(&tmp); \
        } \
-       zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
+       zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
    }
 
 #define ADD_PROPERTY_LONG(_table, _key, _long) \
        { \
-               zval *tmp; \
-               MAKE_STD_ZVAL(tmp); \
-               ZVAL_LONG(tmp, _long); \
-               zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
+               zval tmp; \
+               ZVAL_LONG(&tmp, _long); \
+               zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
        }
 
 #define ADD_PROPERTY_NULL(_table, _key) \
        { \
-               zval *tmp; \
-               MAKE_STD_ZVAL(tmp); \
-               ZVAL_NULL(tmp); \
-               zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
+               zval tmp; \
+               ZVAL_NULL(&tmp); \
+               zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
        }
 
 #define ADD_PROPERTY_BOOL(_table, _key, _bool) \
     { \
-       zval *tmp; \
-       MAKE_STD_ZVAL(tmp); \
-       ZVAL_BOOL(tmp, _bool); \
-       zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
-   }
+               zval tmp; \
+               ZVAL_BOOL(&tmp, _bool); \
+               zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
+       }
 
 #define TIDY_OPEN_BASE_DIR_CHECK(filename) \
 if (php_check_open_basedir(filename TSRMLS_CC)) { \
@@ -195,19 +190,25 @@ struct _PHPTidyDoc {
 };
 
 struct _PHPTidyObj {
-       zend_object             std;
        TidyNode                node;
        tidy_obj_type   type;
        PHPTidyDoc              *ptdoc;
+       zend_object             std;
 };
+
+static inline PHPTidyObj *php_tidy_fetch_object(zend_object *obj) {
+       return (PHPTidyObj *)((char*)(obj) - XtOffsetOf(PHPTidyObj, std));
+}
+
+#define Z_TIDY_P(zv) php_tidy_fetch_object(Z_OBJ_P((zv)))
 /* }}} */
 
 /* {{{ ext/tidy prototypes
 */
-static char *php_tidy_file_to_mem(char *, zend_bool, int * TSRMLS_DC);
-static void tidy_object_free_storage(void * TSRMLS_DC);
-static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC);
-static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
+static zend_string *php_tidy_file_to_mem(char *, zend_bool TSRMLS_DC);
+static void tidy_object_free_storage(zend_object * TSRMLS_DC);
+static zend_object *tidy_object_new_node(zend_class_entry * TSRMLS_DC);
+static zend_object *tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
 static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC);
 static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC);
 static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC);
@@ -552,26 +553,26 @@ static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS
 
 static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file)
 {
-       char *data=NULL, *arg1, *enc = NULL;
-       int arg1_len, enc_len = 0, data_len = 0;
+       char *enc = NULL;
+       int enc_len = 0;
        zend_bool use_include_path = 0;
        TidyDoc doc;
        TidyBuffer *errbuf;
-       zval **config = NULL;
+       zend_string *data, *arg1;
+       zval *config = NULL;
 
        if (is_file) {
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &arg1, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
                        RETURN_FALSE;
                }
-               if (!(data = php_tidy_file_to_mem(arg1, use_include_path, &data_len TSRMLS_CC))) {
+               if (!(data = php_tidy_file_to_mem(arg1->val, use_include_path TSRMLS_CC))) {
                        RETURN_FALSE;
                }
        } else {
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zsb", &arg1, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
                        RETURN_FALSE;
                }
                data = arg1;
-               data_len = arg1_len;
        }
 
        doc = tidyCreate();
@@ -591,7 +592,20 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
        TIDY_SET_DEFAULT_CONFIG(doc);
        
        if (config) {
-               TIDY_APPLY_CONFIG_ZVAL(doc, config);
+        if(Z_TYPE_P(config) == IS_ARRAY) { 
+            _php_tidy_apply_config_array(doc, HASH_OF(config) TSRMLS_CC); 
+        } else { 
+            convert_to_string_ex(config); 
+            TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_P(config)); 
+            switch (tidyLoadConfig(doc, Z_STRVAL_P(config))) { 
+              case -1: 
+                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_P(config)); 
+                break; 
+              case 1: 
+                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_P(config)); 
+                break; 
+            } 
+        } 
        }
 
        if(enc_len) {
@@ -605,7 +619,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
                TidyBuffer buf;
 
                tidyBufInit(&buf);
-               tidyBufAttach(&buf, (byte *) data, data_len);
+               tidyBufAttach(&buf, (byte *) data->val, data->len);
 
                if (tidyParseBuffer(doc, &buf) < 0) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
@@ -617,7 +631,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
 
                                tidySaveBuffer (doc, &output);
                                FIX_BUFFER(&output);
-                               RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1);
+                               RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0);
                                tidyBufFree(&output);
                        } else {
                                RETVAL_FALSE;
@@ -626,7 +640,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
        }
 
        if (is_file) {
-               efree(data);
+               STR_RELEASE(data);
        }
 
        tidyBufFree(errbuf);
@@ -634,26 +648,25 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
        tidyRelease(doc);
 }
 
-static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, int *len TSRMLS_DC)
+static zend_string *php_tidy_file_to_mem(char *filename, zend_bool use_include_path TSRMLS_DC)
 {
        php_stream *stream;
-       char *data = NULL;
+       zend_string *data = NULL;
 
        if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) {
                return NULL;
        }
-       if ((*len = (int) php_stream_copy_to_mem(stream, (void*) &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
-               data = estrdup("");
-               *len = 0;
+       if ((data = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) == NULL) {
+               data = STR_EMPTY_ALLOC();
        }
        php_stream_close(stream);
 
        return data;
 }
 
-static void tidy_object_free_storage(void *object TSRMLS_DC)
+static void tidy_object_free_storage(zend_object *object TSRMLS_DC)
 {
-       PHPTidyObj *intern = (PHPTidyObj *)object;
+       PHPTidyObj *intern = php_tidy_fetch_object(object);
 
        zend_object_std_dtor(&intern->std TSRMLS_CC);
 
@@ -667,17 +680,13 @@ static void tidy_object_free_storage(void *object TSRMLS_DC)
                        efree(intern->ptdoc);
                }
        }
-
-       efree(object);
 }
 
-static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers,
-                                                       zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC)
+static zend_object *tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, tidy_obj_type objtype TSRMLS_DC)
 {
        PHPTidyObj *intern;
 
-       intern = emalloc(sizeof(PHPTidyObj));
-       memset(intern, 0, sizeof(PHPTidyObj));
+       intern = ecalloc(1, sizeof(PHPTidyObj) + sizeof(zval) * (class_type->default_properties_count - 1));
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
 
@@ -711,34 +720,24 @@ static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *
                        break;
        }
 
-       retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) tidy_object_free_storage, NULL TSRMLS_CC);
-       retval->handlers = handlers;
+       intern->std.handlers = handlers;
+
+       return &intern->std;
 }
 
-static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC)
+static zend_object *tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC)
 {
-       zend_object_value retval;
-       tidy_object_new(class_type, &tidy_object_handlers_node, &retval, is_node TSRMLS_CC);
-       return retval;
+       return tidy_object_new(class_type, &tidy_object_handlers_node, is_node TSRMLS_CC);
 }
 
-static zend_object_value tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC)
+static zend_object *tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC)
 {
-       zend_object_value retval;
-       tidy_object_new(class_type, &tidy_object_handlers_doc, &retval, is_doc TSRMLS_CC);
-       return retval;
+       return tidy_object_new(class_type, &tidy_object_handlers_doc, is_doc TSRMLS_CC);
 }
 
 static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
 {
-       if (!object) {
-               ALLOC_ZVAL(object);
-       }
-
-       Z_TYPE_P(object) = IS_OBJECT;
        object_init_ex(object, pce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
        return object;
 }
 
@@ -747,7 +746,7 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
        TidyBuffer output;
        PHPTidyObj *obj;
 
-       switch(type) {
+       switch (type) {
                case IS_LONG:
                        ZVAL_LONG(out, 0);
                        break;
@@ -756,15 +755,15 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
                        ZVAL_DOUBLE(out, 0);
                        break;
 
-               case IS_BOOL:
+               case _IS_BOOL:
                        ZVAL_BOOL(out, TRUE);
                        break;
 
                case IS_STRING:
-                       obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
+                       obj = Z_TIDY_P(in);
                        tidyBufInit(&output);
                        tidySaveBuffer (obj->ptdoc->doc, &output);
-                       ZVAL_STRINGL(out, (char *) output.bp, output.size ? output.size-1 : 0, 1);
+                       ZVAL_STRINGL(out, (char *) output.bp, output.size ? output.size-1 : 0);
                        tidyBufFree(&output);
                        break;
 
@@ -789,16 +788,16 @@ static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
                        ZVAL_DOUBLE(out, 0);
                        break;
 
-               case IS_BOOL:
+               case _IS_BOOL:
                        ZVAL_BOOL(out, TRUE);
                        break;
 
                case IS_STRING:
-                       obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
+                       obj = Z_TIDY_P(in);
                        tidyBufInit(&buf);
                        if (obj->ptdoc) {
                                tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
-                               ZVAL_STRINGL(out, (char *) buf.bp, buf.size-1, 1);
+                               ZVAL_STRINGL(out, (char *) buf.bp, buf.size-1);
                        } else {
                                ZVAL_EMPTY_STRING(out);
                        }
@@ -816,7 +815,7 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
 {
 
        TidyBuffer output;
-       zval *temp;
+       zval temp;
 
        tidyBufInit(&output);
        tidySaveBuffer (obj->ptdoc->doc, &output);
@@ -825,9 +824,8 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
                if (!obj->std.properties) {
                        rebuild_object_properties(&obj->std);
                }
-               MAKE_STD_ZVAL(temp);
-               ZVAL_STRINGL(temp, (char*)output.bp, output.size-1, TRUE);
-               zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL);
+               ZVAL_STRINGL(&temp, (char*)output.bp, output.size-1);
+               zend_hash_str_update(obj->std.properties, "value", sizeof("value") - 1, &temp);
        }
        
        tidyBufFree(&output);
@@ -836,9 +834,8 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
                if (!obj->std.properties) {
                        rebuild_object_properties(&obj->std);
                }
-               MAKE_STD_ZVAL(temp);
-               ZVAL_STRINGL(temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, TRUE);
-               zend_hash_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer"), (void *)&temp, sizeof(zval *), NULL);
+               ZVAL_STRINGL(&temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1);
+               zend_hash_str_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer") - 1, &temp);
        }
 }
 
@@ -848,7 +845,7 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
        TidyBuffer buf;
        TidyAttr        tempattr;
        TidyNode        tempnode;
-       zval *attribute, *children, *temp;
+       zval attribute, children, temp;
        PHPTidyObj *newobj;
 
        switch(type) {
@@ -880,48 +877,45 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
                        }
 
                        tempattr = tidyAttrFirst(obj->node);
-                       MAKE_STD_ZVAL(attribute);
 
                        if (tempattr) {
                                char *name, *val;
-                               array_init(attribute);
+                               array_init(&attribute);
 
                                do {
                                        name = (char *)tidyAttrName(tempattr);
                                        val = (char *)tidyAttrValue(tempattr);
                                        if (name && val) {
-                                               add_assoc_string(attribute, name, val);
+                                               add_assoc_string(&attribute, name, val);
                                        }
                                } while((tempattr = tidyAttrNext(tempattr)));
                        } else {
-                               ZVAL_NULL(attribute);
+                               ZVAL_NULL(&attribute);
                        }
-                       zend_hash_update(obj->std.properties, "attribute", sizeof("attribute"), (void *)&attribute, sizeof(zval *), NULL);
+                       zend_hash_str_update(obj->std.properties, "attribute", sizeof("attribute") - 1, &attribute);
 
                        tempnode = tidyGetChild(obj->node);
 
-                       MAKE_STD_ZVAL(children);
                        if (tempnode) {
-                               array_init(children);
+                               array_init(&children);
                                do {
-                                       MAKE_STD_ZVAL(temp);
-                                       tidy_instanciate(tidy_ce_node, temp TSRMLS_CC);
-                                       newobj = (PHPTidyObj *) zend_object_store_get_object(temp TSRMLS_CC);
+                                       tidy_instanciate(tidy_ce_node, &temp TSRMLS_CC);
+                                       newobj = Z_TIDY_P(&temp);
                                        newobj->node = tempnode;
                                        newobj->type = is_node;
                                        newobj->ptdoc = obj->ptdoc;
                                        newobj->ptdoc->ref_count++;
 
                                        tidy_add_default_properties(newobj, is_node TSRMLS_CC);
-                                       add_next_index_zval(children, temp);
+                                       add_next_index_zval(&children, &temp);
 
                                } while((tempnode = tidyGetNext(tempnode)));
 
                        } else {
-                               ZVAL_NULL(children);
+                               ZVAL_NULL(&children);
                        }
 
-                       zend_hash_update(obj->std.properties, "child", sizeof("child"), (void *)&children, sizeof(zval *), NULL);
+                       zend_hash_str_update(obj->std.properties, "child", sizeof("child") - 1, &children);
 
                        break;
 
@@ -996,7 +990,7 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp
        }
 
        tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
-       newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
+       newobj = Z_TIDY_P(return_value);
        newobj->type  = is_node;
        newobj->ptdoc = obj->ptdoc;
        newobj->node  = node;
@@ -1007,34 +1001,16 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp
 
 static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
 {
-       char *opt_name;
-       zval **opt_val;
+       zval *opt_val;
        ulong opt_indx;
-       uint opt_name_len;
-       zend_bool clear_str;
-
-       for (zend_hash_internal_pointer_reset(ht_options);
-                zend_hash_get_current_data(ht_options, (void *) &opt_val) == SUCCESS;
-                zend_hash_move_forward(ht_options)) {
-
-               switch (zend_hash_get_current_key_ex(ht_options, &opt_name, &opt_name_len, &opt_indx, FALSE, NULL)) {
-                       case HASH_KEY_IS_STRING:
-                       clear_str = 0;
-                       break;
-
-                       case HASH_KEY_IS_LONG:
-                       continue; /* ignore numeric keys */
-
-                       default:
-                       php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
-                       return FAILURE;
-               }
+       zend_string *opt_name;
 
-               _php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC);
-               if (clear_str) {
-                       efree(opt_name);
+       ZEND_HASH_FOREACH_KEY_VAL(ht_options, opt_indx, opt_name, opt_val) {
+               if (opt_name == NULL) {
+                       continue;
                }
-       }
+               _php_tidy_set_tidy_opt(doc, opt_name->val, opt_val TSRMLS_CC);
+       } ZEND_HASH_FOREACH_END();
        
        return SUCCESS;
 }
@@ -1077,6 +1053,9 @@ static PHP_MINIT_FUNCTION(tidy)
        tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler;
        tidy_object_handlers_node.cast_object = tidy_node_cast_handler;
 
+       tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = XtOffsetOf(PHPTidyObj, std);
+       tidy_object_handlers_node.free_obj = tidy_object_handlers_doc.free_obj = tidy_object_free_storage;
+
        _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU);
        _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU);
 
@@ -1215,23 +1194,23 @@ static int php_tidy_output_handler(void **nothing, php_output_context *output_co
    Parse a document stored in a string */
 static PHP_FUNCTION(tidy_parse_string)
 {
-       char *input, *enc = NULL;
-       int input_len, enc_len = 0;
-       zval **options = NULL;
+       char *enc = NULL;
+       int enc_len = 0;
+       zend_string *input;
+       zval *options = NULL;
        PHPTidyObj *obj;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zs", &input, &options, &enc, &enc_len) == FAILURE) {
                RETURN_FALSE;
        }
 
        tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
-       obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
+       obj = Z_TIDY_P(return_value);
                
        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
        
-       if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == FAILURE) {
-               zval_dtor(return_value);
-               INIT_ZVAL(*return_value);
+       if (php_tidy_parse_string(obj, input->val, input->len, enc TSRMLS_CC) == FAILURE) {
+               zval_ptr_dtor(return_value);
                RETURN_FALSE;
        }
 }
@@ -1244,7 +1223,7 @@ static PHP_FUNCTION(tidy_get_error_buffer)
        TIDY_FETCH_OBJECT;
 
        if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) {
-               RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, 1);
+               RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1);
        } else {
                RETURN_FALSE;
        }
@@ -1261,7 +1240,7 @@ static PHP_FUNCTION(tidy_get_output)
        tidyBufInit(&output);
        tidySaveBuffer(obj->ptdoc->doc, &output);
        FIX_BUFFER(&output);
-       RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1);
+       RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0);
        tidyBufFree(&output);
 }
 /* }}} */
@@ -1270,36 +1249,35 @@ static PHP_FUNCTION(tidy_get_output)
    Parse markup in file or URI */
 static PHP_FUNCTION(tidy_parse_file)
 {
-       char *inputfile, *enc = NULL;
-       int input_len, contents_len, enc_len = 0;
+       char *enc = NULL;
+       int enc_len = 0;
        zend_bool use_include_path = 0;
-       char *contents;
-       zval **options = NULL;
+       zend_string *inputfile, *contents;
+       zval *options = NULL;
        
        PHPTidyObj *obj;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &inputfile, &input_len,
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &inputfile,
                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                RETURN_FALSE;
        }
 
        tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
-       obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
+       obj = Z_TIDY_P(return_value);
 
-       if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
+       if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
                RETURN_FALSE;
        }
 
        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
 
-       if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
-               zval_dtor(return_value);
-               INIT_ZVAL(*return_value);
+       if (php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC) == FAILURE) {
+               zval_ptr_dtor(return_value);
                RETVAL_FALSE;
        }
 
-       efree(contents);
+       STR_RELEASE(contents);
 }
 /* }}} */
 
@@ -1357,7 +1335,7 @@ static PHP_FUNCTION(tidy_get_release)
                return;
        }
 
-       RETURN_STRING((char *)tidyReleaseDate(), 1);
+       RETURN_STRING((char *)tidyReleaseDate());
 }
 /* }}} */
 
@@ -1384,7 +1362,7 @@ static PHP_FUNCTION(tidy_get_opt_doc)
                }
        }
 
-       obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
+       obj = Z_TIDY_P(object);
 
        opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
 
@@ -1394,7 +1372,7 @@ static PHP_FUNCTION(tidy_get_opt_doc)
        }
 
        if ( (optval = (char *) tidyOptGetDoc(obj->ptdoc->doc, opt)) ) {
-               RETURN_STRING(optval, 1);
+               RETURN_STRING(optval);
        }
 
        RETURN_FALSE;
@@ -1547,7 +1525,7 @@ static PHP_FUNCTION(tidy_getopt)
                }
        }
 
-       obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
+       obj = Z_TIDY_P(object);
 
        opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
 
@@ -1559,8 +1537,9 @@ static PHP_FUNCTION(tidy_getopt)
        optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
        switch (optt) {
                case TidyString:
-                       RETURN_STRING((char *)optval, 0);
-                       break;
+                       RETVAL_STRING((char *)optval);
+                       efree(optval);
+                       return;
 
                case TidyInteger:
                        RETURN_LONG((long)optval);
@@ -1585,88 +1564,89 @@ static PHP_FUNCTION(tidy_getopt)
 
 static TIDY_DOC_METHOD(__construct)
 {
-       char *inputfile = NULL, *enc = NULL;
-       int input_len = 0, enc_len = 0, contents_len = 0;
+       char *enc = NULL;
+       int enc_len = 0;
        zend_bool use_include_path = 0;
-       char *contents;
-       zval **options = NULL;
+       zval *options = NULL;
+       zend_string *contents, *inputfile = NULL;
        
        PHPTidyObj *obj;
        TIDY_SET_CONTEXT;       
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|pZsb", &inputfile, &input_len,
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Pzsb", &inputfile,
                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                RETURN_FALSE;
        }
        
-       obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
+       obj = Z_TIDY_P(object);
        
        if (inputfile) {
-               if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
+               if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
                        return;
                }
 
                TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
 
-               php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC);
+               php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC);
 
-               efree(contents);
+               STR_RELEASE(contents);
        }
 }
 
 static TIDY_DOC_METHOD(parseFile)
 {
-       char *inputfile, *enc = NULL;
-       int input_len, enc_len = 0, contents_len = 0;
+       char *enc = NULL;
+       int enc_len = 0;
        zend_bool use_include_path = 0;
-       char *contents;
-       zval **options = NULL;
+       zval *options = NULL;
+       zend_string *inputfile, *contents;
        PHPTidyObj *obj;
 
        TIDY_SET_CONTEXT;
 
-       obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
+       obj = Z_TIDY_P(object);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &inputfile, &input_len,
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &inputfile,
                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                RETURN_FALSE;
        }
        
-       if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
+       if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
                RETURN_FALSE;
        }
 
        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
 
-       if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
+       if (php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC) == FAILURE) {
                RETVAL_FALSE;
        } else {
                RETVAL_TRUE;
        }
 
-       efree(contents);
+       STR_RELEASE(contents);
 }
 
 static TIDY_DOC_METHOD(parseString)
 {
-       char *input, *enc = NULL;
-       int input_len, enc_len = 0;
-       zval **options = NULL;
+       char *enc = NULL;
+       int enc_len = 0;
+       zval *options = NULL;
        PHPTidyObj *obj;
+       zend_string *input;
 
        TIDY_SET_CONTEXT;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zs", &input, &options, &enc, &enc_len) == FAILURE) {
                RETURN_FALSE;
        }
 
-       obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
+       obj = Z_TIDY_P(object);
 
        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
 
-       if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == SUCCESS) {
+       if(php_tidy_parse_string(obj, input->val, input->len, enc TSRMLS_CC) == SUCCESS) {
                RETURN_TRUE;
        }
        
@@ -1829,7 +1809,7 @@ static TIDY_NODE_METHOD(getParent)
        parent_node = tidyGetParent(obj->node);
        if(parent_node) {
                tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
-               newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
+               newobj = Z_TIDY_P(return_value);
                newobj->node = parent_node;
                newobj->type = is_node;
                newobj->ptdoc = obj->ptdoc;