From e47587e189f8ca8b84355ba352c93b7f11292ef1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 15 Aug 2005 14:39:18 +0000 Subject: [PATCH] Fixed several unicode related bugs --- Zend/zend.c | 6 ++++++ Zend/zend_API.c | 2 +- Zend/zend_API.h | 1 + Zend/zend_builtin_functions.c | 29 ++++++++++++++++++----------- Zend/zend_compile.c | 2 +- Zend/zend_constants.c | 2 +- Zend/zend_hash.c | 13 ++++++++----- Zend/zend_object_handlers.c | 5 ++++- Zend/zend_objects.c | 2 +- Zend/zend_operators.c | 2 +- 10 files changed, 42 insertions(+), 22 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 35d4f43174..b904fbd0f1 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -320,6 +320,12 @@ static void print_flat_hash(HashTable *ht TSRMLS_DC) case HASH_KEY_IS_STRING: ZEND_PUTS(string_key); break; + case HASH_KEY_IS_BINARY: + zend_printf("b\"%s\"", string_key); + break; + case HASH_KEY_IS_UNICODE: + zend_printf("%r", string_key); + break; case HASH_KEY_IS_LONG: zend_printf("%ld", num_key); break; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f6ac43a800..f1cac21a14 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -165,7 +165,7 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_arr ALLOC_ZVAL(value_ptr); *value_ptr = **value; INIT_PZVAL(value_ptr); - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", class_name); if(!dup) { efree(class_name); } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 8442d38cf1..0a425e8fa7 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -218,6 +218,7 @@ ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, char *name, int name_length, char *value, int value_len, int access_type TSRMLS_DC); ZEND_API int zend_u_declare_property(zend_class_entry *ce, zend_uchar type, void *name, int name_length, zval *property, int access_type TSRMLS_DC); +ZEND_API int zend_u_declare_property_ex(zend_class_entry *ce, zend_uchar type, void *name, int name_length, zval *property, int access_type, char *doc_comment, int doc_comment_len TSRMLS_DC); ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC); ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c1ca31c25e..10296d09a9 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -920,8 +920,8 @@ ZEND_FUNCTION(method_exists) } if (Z_TYPE_PP(klass) == IS_OBJECT) { ce = Z_OBJCE_PP(klass); - } else if (Z_TYPE_PP(klass) == IS_STRING) { - if (zend_lookup_class(Z_STRVAL_PP(klass), Z_STRLEN_PP(klass), &pce TSRMLS_CC) == FAILURE) { + } else if (Z_TYPE_PP(klass) == IS_STRING || Z_TYPE_PP(klass) == IS_UNICODE) { + if (zend_u_lookup_class(Z_TYPE_PP(klass), Z_STRVAL_PP(klass), Z_STRLEN_PP(klass), &pce TSRMLS_CC) == FAILURE) { RETURN_FALSE; } ce = *pce; @@ -929,7 +929,9 @@ ZEND_FUNCTION(method_exists) RETURN_FALSE; } - convert_to_string_ex(method_name); + if (Z_TYPE_PP(method_name) != IS_STRING || Z_TYPE_PP(method_name) == IS_UNICODE) { + convert_to_text_ex(method_name); + } lcname = zend_u_str_case_fold(Z_TYPE_PP(method_name), Z_UNIVAL_PP(method_name), Z_UNILEN_PP(method_name), 1, &lcname_len); if (zend_u_hash_exists(&ce->function_table, Z_TYPE_PP(method_name), lcname, lcname_len+1)) { efree(lcname); @@ -968,17 +970,22 @@ ZEND_FUNCTION(property_exists) if (ZEND_NUM_ARGS()!= 2 || zend_get_parameters_ex(2, &object, &property)==FAILURE) { ZEND_WRONG_PARAM_COUNT(); } - convert_to_string_ex(property); - if (!Z_STRLEN_PP(property)) { + + if (Z_TYPE_PP(property) != IS_STRING && Z_TYPE_PP(property) != IS_UNICODE) { + convert_to_text_ex(property); + } + + if (!Z_UNILEN_PP(property)) { RETURN_FALSE; } switch((*object)->type) { case IS_STRING: - if (!Z_STRLEN_PP(object)) { + case IS_UNICODE: + if (!Z_UNILEN_PP(object)) { RETURN_FALSE; } - if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) { + if (zend_u_lookup_class(Z_TYPE_PP(object), Z_UNIVAL_PP(object), Z_UNILEN_PP(object), &pce TSRMLS_CC) == SUCCESS) { ce = *pce; } else { RETURN_FALSE; @@ -992,14 +999,14 @@ ZEND_FUNCTION(property_exists) if (property_info->flags & ZEND_ACC_PUBLIC) { RETURN_TRUE; } - zend_unmangle_property_name(property_info->name, &class_name, &prop_name); - if (!strncmp(class_name, "*", 1)) { + zend_u_unmangle_property_name(Z_TYPE_PP(property), property_info->name, &class_name, &prop_name); + if (class_name[0] == '*') { if (instanceof_function(EG(scope), ce TSRMLS_CC)) { RETURN_TRUE; } RETURN_FALSE; } - if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) { + if (zend_u_lookup_class(Z_TYPE_PP(object), Z_UNIVAL_PP(object), Z_UNILEN_PP(object), &pce TSRMLS_CC) == SUCCESS) { ce = *pce; } else { RETURN_FALSE; /* shouldn't happen */ @@ -1880,7 +1887,7 @@ ZEND_FUNCTION(debug_print_backtrace) zend_printf("#%-2d ", indent); if (class_name) { if (UG(unicode)) { - zend_printf("%r(", class_name); + zend_printf("%r", class_name); } else { ZEND_PUTS(class_name); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 319bdb8e25..947cd7e465 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2962,7 +2962,7 @@ void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_ty CG(doc_comment_len) = 0; } - zend_u_declare_property(CG(active_class_entry), Z_TYPE(var_name->u.constant), Z_UNIVAL(var_name->u.constant), Z_UNILEN(var_name->u.constant), property, access_type TSRMLS_CC); + zend_u_declare_property_ex(CG(active_class_entry), Z_TYPE(var_name->u.constant), Z_UNIVAL(var_name->u.constant), Z_UNILEN(var_name->u.constant), property, access_type, comment, comment_len TSRMLS_CC); efree(var_name->u.constant.value.str.val); } diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 613bc0a962..1389144abb 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -332,7 +332,7 @@ ZEND_API int zend_u_register_constant(zend_uchar type, zend_constant *c TSRMLS_D } if (zend_u_hash_add(EG(zend_constants), type, name, lookup_name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) { - zend_error(E_NOTICE,"Constant %s already defined", name); + zend_error(E_NOTICE,"Constant %R already defined", type, name); free(c->name); if (!(c->flags & CONST_PERSISTENT)) { zval_dtor(&c->value); diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index e020319ab0..bfe203d088 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1297,6 +1297,7 @@ ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosi ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char *str_index, uint str_length, ulong num_index, HashPosition *pos) { Bucket *p; + uint real_length; p = pos ? (*pos) : ht->pInternalPointer; @@ -1304,12 +1305,13 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char * if (p) { if (key_type == HASH_KEY_IS_LONG) { - str_length = 0; + real_length = str_length = 0; if (!p->nKeyLength && p->h == num_index) { return SUCCESS; } zend_hash_index_del(ht, num_index); } else if (key_type == HASH_KEY_IS_STRING || key_type == HASH_KEY_IS_BINARY) { + real_length = str_length; if (p->nKeyLength == str_length && p->key.type == ((key_type == HASH_KEY_IS_STRING)?IS_STRING:IS_BINARY) && memcmp(p->key.u.string, str_index, str_length) == 0) { @@ -1317,9 +1319,10 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char * } zend_u_hash_del(ht, (key_type == HASH_KEY_IS_STRING)?IS_STRING:IS_BINARY, str_index, str_length); } else if (key_type == HASH_KEY_IS_UNICODE) { + real_length = str_length * sizeof(UChar); if (p->nKeyLength == str_length && p->key.type == IS_UNICODE && - memcmp(p->key.u.string, str_index, str_length * sizeof(UChar*)) == 0) { + memcmp(p->key.u.string, str_index, real_length) == 0) { return SUCCESS; } zend_u_hash_del(ht, IS_UNICODE, str_index, str_length); @@ -1339,7 +1342,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char * } if (p->nKeyLength != str_length) { - Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) - 1 + str_length, ht->persistent); + Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) - 1 + real_length, ht->persistent); q->nKeyLength = str_length; if (p->pData == &p->pDataPtr) { @@ -1373,11 +1376,11 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char * if (key_type == HASH_KEY_IS_LONG) { p->h = num_index; } else if (key_type == HASH_KEY_IS_UNICODE) { - memcpy(p->key.u.unicode, str_index, str_length * sizeof(UChar)); + memcpy(p->key.u.unicode, str_index, real_length); p->key.type = IS_UNICODE; p->h = zend_u_inline_hash_func(IS_UNICODE, str_index, str_length); } else { - memcpy(p->key.u.string, str_index, str_length); + memcpy(p->key.u.string, str_index, real_length); p->key.type = (key_type == HASH_KEY_IS_STRING)?IS_STRING:IS_BINARY; p->h = zend_u_inline_hash_func(p->key.type, str_index, str_length); } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 3a5014c948..c707126ac4 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -266,7 +266,10 @@ ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name if (!(property_info->flags & ZEND_ACC_PRIVATE)) { /* we we're looking for a private prop but found a non private one of the same name */ return FAILURE; - } else if (strcmp(prop_info_name+1, property_info->name+1)) { + } else if (!UG(unicode) && strcmp(prop_info_name+1, property_info->name+1)) { + /* we we're looking for a private prop but found a private one of the same name but another class */ + return FAILURE; + } else if (UG(unicode) && u_strcmp(((UChar*)prop_info_name)+1, ((UChar*)property_info->name)+1)) { /* we we're looking for a private prop but found a private one of the same name but another class */ return FAILURE; } diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 83f0d809b5..c9299c4efb 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -119,7 +119,7 @@ static void zval_add_ref_or_clone(zval **p) TSRMLS_FETCH(); if (Z_OBJ_HANDLER_PP(p, clone_obj) == NULL) { - zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_PP(p)->name); + zend_error(E_ERROR, "Trying to clone an uncloneable object of class %v", Z_OBJCE_PP(p)->name); } else { zval *orig = *p; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index fc032d4c32..1de3975a20 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -398,7 +398,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) retval = (zend_hash_num_elements(ht)?1:0); } } else { - zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name); + zend_error(E_NOTICE, "Object of class %v could not be converted to int", Z_OBJCE_P(op)->name); } zval_dtor(op); ZVAL_LONG(op, retval); -- 2.50.1