Back to index

php5  5.3.10
incomplete_class.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author:  Sascha Schumann <sascha@schumann.cx>                        |
00016    +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: incomplete_class.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include "php.h"
00022 #include "basic_functions.h"
00023 #include "php_incomplete_class.h"
00024 
00025 #define INCOMPLETE_CLASS_MSG \
00026               "The script tried to execute a method or "  \
00027               "access a property of an incomplete object. " \
00028               "Please ensure that the class definition \"%s\" of the object " \
00029               "you are trying to operate on was loaded _before_ " \
00030               "unserialize() gets called or provide a __autoload() function " \
00031               "to load the class definition "
00032 
00033 static zend_object_handlers php_incomplete_object_handlers;
00034 
00035 /* {{{ incomplete_class_message
00036  */
00037 static void incomplete_class_message(zval *object, int error_type TSRMLS_DC)
00038 {
00039        char *class_name;
00040        zend_bool class_name_alloced = 1;
00041 
00042        class_name = php_lookup_class_name(object, NULL);
00043        
00044        if (!class_name) {
00045               class_name_alloced = 0;
00046               class_name = "unknown";
00047        }
00048        
00049        php_error_docref(NULL TSRMLS_CC, error_type, INCOMPLETE_CLASS_MSG, class_name);
00050 
00051        if (class_name_alloced) {
00052               efree(class_name);
00053        }
00054 }
00055 /* }}} */
00056 
00057 static zval *incomplete_class_get_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */
00058 {
00059        incomplete_class_message(object, E_NOTICE TSRMLS_CC);
00060        
00061        if (type == BP_VAR_W || type == BP_VAR_RW) {
00062               return EG(error_zval_ptr);
00063        } else {
00064               return EG(uninitialized_zval_ptr);
00065        }
00066 }
00067 /* }}} */
00068 
00069 static void incomplete_class_write_property(zval *object, zval *member, zval *value TSRMLS_DC) /* {{{ */
00070 {
00071        incomplete_class_message(object, E_NOTICE TSRMLS_CC);
00072 }
00073 /* }}} */
00074        
00075 static zval **incomplete_class_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC) /* {{{ */
00076 {
00077        incomplete_class_message(object, E_NOTICE TSRMLS_CC);
00078        return &EG(error_zval_ptr);
00079 }
00080 /* }}} */
00081 
00082 static void incomplete_class_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{ */
00083 {
00084        incomplete_class_message(object, E_NOTICE TSRMLS_CC);
00085 }
00086 /* }}} */
00087 
00088 static int incomplete_class_has_property(zval *object, zval *member, int check_empty TSRMLS_DC) /* {{{ */
00089 {
00090        incomplete_class_message(object, E_NOTICE TSRMLS_CC);
00091        return 0;
00092 }
00093 /* }}} */
00094 
00095 static union _zend_function *incomplete_class_get_method(zval **object, char *method, int method_len TSRMLS_DC) /* {{{ */
00096 {
00097        incomplete_class_message(*object, E_ERROR TSRMLS_CC);
00098        return NULL;
00099 }
00100 /* }}} */
00101 
00102 /* {{{ php_create_incomplete_class
00103  */
00104 static zend_object_value php_create_incomplete_object(zend_class_entry *class_type TSRMLS_DC)
00105 {
00106        zend_object *object;
00107        zend_object_value value;
00108        
00109        value = zend_objects_new(&object, class_type TSRMLS_CC);
00110        value.handlers = &php_incomplete_object_handlers;
00111        
00112        ALLOC_HASHTABLE(object->properties);
00113        zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
00114        return value;
00115 }
00116 
00117 PHPAPI zend_class_entry *php_create_incomplete_class(TSRMLS_D)
00118 {
00119        zend_class_entry incomplete_class;
00120 
00121        INIT_CLASS_ENTRY(incomplete_class, INCOMPLETE_CLASS, NULL);
00122        incomplete_class.create_object = php_create_incomplete_object;
00123 
00124        memcpy(&php_incomplete_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
00125        php_incomplete_object_handlers.read_property = incomplete_class_get_property;
00126        php_incomplete_object_handlers.has_property = incomplete_class_has_property;
00127        php_incomplete_object_handlers.unset_property = incomplete_class_unset_property;
00128        php_incomplete_object_handlers.write_property = incomplete_class_write_property;
00129        php_incomplete_object_handlers.get_property_ptr_ptr = incomplete_class_get_property_ptr_ptr;
00130     php_incomplete_object_handlers.get_method = incomplete_class_get_method;
00131        
00132        return zend_register_internal_class(&incomplete_class TSRMLS_CC);
00133 }
00134 /* }}} */
00135 
00136 /* {{{ php_lookup_class_name
00137  */
00138 PHPAPI char *php_lookup_class_name(zval *object, zend_uint *nlen)
00139 {
00140        zval **val;
00141        char *retval = NULL;
00142        HashTable *object_properties;
00143        TSRMLS_FETCH();
00144 
00145        object_properties = Z_OBJPROP_P(object);
00146 
00147        if (zend_hash_find(object_properties, MAGIC_MEMBER, sizeof(MAGIC_MEMBER), (void **) &val) == SUCCESS) {
00148               retval = estrndup(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
00149 
00150               if (nlen) {
00151                      *nlen = Z_STRLEN_PP(val);
00152               }
00153        }
00154 
00155        return retval;
00156 }
00157 /* }}} */
00158 
00159 /* {{{ php_store_class_name
00160  */
00161 PHPAPI void php_store_class_name(zval *object, const char *name, zend_uint len)
00162 {
00163        zval *val;
00164        TSRMLS_FETCH();
00165 
00166        MAKE_STD_ZVAL(val);
00167 
00168        Z_TYPE_P(val)   = IS_STRING;
00169        Z_STRVAL_P(val) = estrndup(name, len);
00170        Z_STRLEN_P(val) = len;
00171 
00172        zend_hash_update(Z_OBJPROP_P(object), MAGIC_MEMBER, sizeof(MAGIC_MEMBER), &val, sizeof(val), NULL);
00173 }
00174 /* }}} */
00175 
00176 /*
00177  * Local variables:
00178  * tab-width: 4
00179  * c-basic-offset: 4
00180  * End:
00181  * vim600: sw=4 ts=4 fdm=marker
00182  * vim<600: sw=4 ts=4
00183  */