From 82a504721e3c6c7e3b75f00e6f8f1a077e24ed2d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 15 Aug 2005 16:13:02 +0000 Subject: [PATCH] Unicode support --- Zend/zend.h | 2 +- ext/pdo/pdo_dbh.c | 14 +++++------ ext/pdo/pdo_stmt.c | 63 +++++++++++++++++----------------------------- 3 files changed, 31 insertions(+), 48 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index 715a9e25789..25615516035 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -551,7 +551,7 @@ ZEND_API void zend_error(int type, const char *format, ...); void zenderror(char *error); /* The following #define is used for code duality in PHP for Engine 1 & 2 */ -#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def +#define ZEND_STANDARD_CLASS_DEF_PTR U_CLASS_ENTRY(zend_standard_class_def) extern ZEND_API zend_class_entry *zend_standard_class_def; extern ZEND_API zend_utility_values zend_uv; extern ZEND_API zval zval_used_for_init; diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 83de7012cda..dde78e4a9fe 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -501,8 +501,8 @@ static PHP_METHOD(PDO, prepare) if (ZEND_NUM_ARGS() > 1 && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS, (void**)&opt)) { if (zend_hash_index_find(Z_ARRVAL_PP(opt), 0, (void**)&item) == FAILURE - || Z_TYPE_PP(item) != IS_STRING - || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE + || (Z_TYPE_PP(item) != IS_STRING && Z_TYPE_PP(item) != IS_UNICODE) + || zend_u_lookup_class(Z_TYPE_PP(item), Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE ) { pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); " @@ -1054,11 +1054,11 @@ static union _zend_function *dbh_method_get( zval *object = *object_pp; #endif pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); + zend_uchar ztype = UG(unicode)?IS_UNICODE:IS_STRING; - lc_method_name = emalloc(method_len + 1); - zend_str_tolower_copy(lc_method_name, method_name, method_len); + lc_method_name = zend_u_str_tolower_dup(ztype, method_name, method_len); - if (zend_hash_find(&dbh->ce->function_table, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + if (zend_u_hash_find(&dbh->ce->function_table, ztype, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { /* not a pre-defined method, nor a user-defined method; check * the driver specific methods */ if (!dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH]) { @@ -1069,8 +1069,8 @@ static union _zend_function *dbh_method_get( } } - if (zend_hash_find(dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH], - lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + if (zend_u_hash_find(dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH], + ztype, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { fbc = NULL; goto out; } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index fd16b0cc05b..b3222a6c7ff 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -620,7 +620,7 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args TSRMLS_DC) /* {{{ */ { zval **object = NULL, **method; - char *fname, *cname; + char *fname; zend_class_entry * ce = NULL, **pce; zend_function *function_handler; @@ -632,7 +632,13 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * object = (zval**)Z_ARRVAL_P(callable)->pListHead->pData; method = (zval**)Z_ARRVAL_P(callable)->pListHead->pListNext->pData; - if (Z_TYPE_PP(object) == IS_STRING) { /* static call */ + if (Z_TYPE_PP(object) == IS_STRING || Z_TYPE_PP(object) == IS_UNICODE) { /* static call */ + if (zend_u_lookup_class(Z_TYPE_PP(object), Z_UNIVAL_PP(object), Z_UNILEN_PP(object), &pce TSRMLS_CC) == FAILURE) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC); + return 0; + } else { + ce = *pce; + } object = NULL; } else if (Z_TYPE_PP(object) == IS_OBJECT) { /* object call */ ce = Z_OBJCE_PP(object); @@ -641,48 +647,25 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * return 0; } - if (Z_TYPE_PP(method) != IS_STRING) { + if (Z_TYPE_PP(method) != IS_STRING && Z_TYPE_PP(method) != IS_UNICODE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback; bogus method name" TSRMLS_CC); return 0; } + } else if (Z_TYPE_P(callable) == IS_STRING || Z_TYPE_P(callable) == IS_UNICODE) { + method = &callable; } if (!zend_is_callable(callable, 0, &fname)) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC); return 0; } - - /* ATM we do not support array($obj, "CLASS::FUNC") or "CLASS_FUNC" */ - cname = fname; - if ((fname = strstr(fname, "::")) == NULL) { - fname = cname; - cname = NULL; - } else { - *fname = '\0'; - fname += 2; - } - if (cname) { - if (zend_lookup_class(cname, strlen(cname), &pce TSRMLS_CC) == FAILURE) { - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC); - return 0; - } else { - if (ce) { - /* pce must be base of ce or ce itself */ - if (ce != *pce && !instanceof_function(ce, *pce TSRMLS_CC)) { - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class has bogus lineage" TSRMLS_CC); - return 0; - } - } - ce = *pce; - } - } - + fci->function_table = ce ? &ce->function_table : EG(function_table); - if (zend_hash_find(fci->function_table, fname, strlen(fname)+1, (void **)&function_handler) == FAILURE) { + if (zend_u_hash_find(fci->function_table, Z_TYPE_PP(method), Z_UNIVAL_PP(method), Z_UNILEN_PP(method)+1, (void **)&function_handler) == FAILURE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function does not exist" TSRMLS_CC); return 0; } - efree(cname ? cname : fname); + efree(fname); fci->size = sizeof(zend_fcall_info); fci->function_name = NULL; @@ -1155,7 +1138,7 @@ static PHP_METHOD(PDOStatement, fetchObject) switch(ZEND_NUM_ARGS()) { case 0: - stmt->fetch.cls.ce = zend_standard_class_def; + stmt->fetch.cls.ce = U_CLASS_ENTRY(zend_standard_class_def); break; case 2: if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) { @@ -1251,7 +1234,7 @@ static PHP_METHOD(PDOStatement, fetchAll) switch(ZEND_NUM_ARGS()) { case 0: case 1: - stmt->fetch.cls.ce = zend_standard_class_def; + stmt->fetch.cls.ce = U_CLASS_ENTRY(zend_standard_class_def); break; case 3: if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) { @@ -1265,12 +1248,12 @@ static PHP_METHOD(PDOStatement, fetchAll) /* no break */ case 2: stmt->fetch.cls.ctor_args = ctor_args; /* we're not going to free these */ - if (Z_TYPE_P(arg2) != IS_STRING) { + if (Z_TYPE_P(arg2) != IS_STRING && Z_TYPE_P(arg2) != IS_UNICODE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Invalid class name (should be a string)" TSRMLS_CC); error = 1; break; } else { - stmt->fetch.cls.ce = zend_fetch_class(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + stmt->fetch.cls.ce = zend_u_fetch_class(Z_TYPE_P(arg2), Z_STRVAL_P(arg2), Z_STRLEN_P(arg2), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (!stmt->fetch.cls.ce) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not find user-specified class" TSRMLS_CC); error = 1; @@ -1889,11 +1872,11 @@ static union _zend_function *dbstmt_method_get( #if PHP_API_VERSION >= 20041225 zval *object = *object_pp; #endif + zend_uchar ztype = UG(unicode)?IS_UNICODE:IS_STRING; - lc_method_name = emalloc(method_len + 1); - zend_str_tolower_copy(lc_method_name, method_name, method_len); + lc_method_name = zend_u_str_tolower_dup(ztype, method_name, method_len); - if (zend_hash_find(&pdo_dbstmt_ce->function_table, lc_method_name, + if (zend_u_hash_find(&U_CLASS_ENTRY(pdo_dbstmt_ce)->function_table, ztype, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC); /* not a pre-defined method, nor a user-defined method; check @@ -1906,8 +1889,8 @@ static union _zend_function *dbstmt_method_get( } } - if (zend_hash_find(stmt->dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_STMT], - lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + if (zend_u_hash_find(stmt->dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_STMT], + ztype, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { fbc = NULL; goto out; }