]> granicus.if.org Git - php/commitdiff
Fix Bug #11345 Seg fault after NLS environment initialization error
authorChristopher Jones <sixd@php.net>
Sat, 30 Jun 2007 02:30:35 +0000 (02:30 +0000)
committerChristopher Jones <sixd@php.net>
Sat, 30 Jun 2007 02:30:35 +0000 (02:30 +0000)
ext/pdo_oci/oci_driver.c
ext/pdo_oci/oci_statement.c
ext/pdo_oci/php_pdo_oci_int.h
ext/pdo_oci/tests/pecl_bug_11345.phpt [new file with mode: 0644]

index 7b7db287aa6075a33d901b19f3705a3121150f2d..6807b075002674838d109510a43685cb4ecbd6bf 100755 (executable)
@@ -55,7 +55,7 @@ static int pdo_oci_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info
 }
 /* }}} */
 
-ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, const char *file, int line TSRMLS_DC) /* {{{ */
+ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, int isinit, const char *file, int line TSRMLS_DC) /* {{{ */
 {
        text errbuf[1024] = "<<Unknown>>";
        char tmp_buf[2048];
@@ -63,7 +63,7 @@ ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, swor
        pdo_oci_error_info *einfo;
        pdo_oci_stmt *S = NULL;
        pdo_error_type *pdo_err = &dbh->error_code;
-       
+
        if (stmt) {
                S = (pdo_oci_stmt*)stmt->driver_data;
                einfo = &S->einfo;
@@ -78,90 +78,97 @@ ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, swor
                        pefree(einfo->errmsg, dbh->is_persistent);
                }
        }
-       
+
        einfo->errmsg = NULL;
        einfo->errcode = 0;
        einfo->file = file;
        einfo->line = line;
-       
-       switch (status) {
-               case OCI_SUCCESS:
-                       strcpy(*pdo_err, "00000");
-                       break;
-               case OCI_ERROR:
-                       OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: %s (%s:%d)", what, errbuf, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_SUCCESS_WITH_INFO:
-                       OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_SUCCESS_WITH_INFO: %s (%s:%d)", what, errbuf, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_NEED_DATA:
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_NEED_DATA (%s:%d)", what, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_NO_DATA:
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_NO_DATA (%s:%d)", what, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_INVALID_HANDLE:
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_INVALID_HANDLE (%s:%d)", what, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_STILL_EXECUTING:
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_STILL_EXECUTING (%s:%d)", what, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-               case OCI_CONTINUE:
-                       slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_CONTINUE (%s:%d)", what, file, line);
-                       einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
-                       break;
-       }
 
-       if (einfo->errcode) {
-               switch (einfo->errcode) {
-                       case 1013:      /* user requested cancel of current operation */
-                               zend_bailout();
+       if (isinit) { /* Initialization error */
+               strcpy(*pdo_err, "HY000");
+               slprintf(tmp_buf, sizeof(tmp_buf), "%s (%s:%d)", what, file, line);
+               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
+       }
+       else {
+               switch (status) {
+                       case OCI_SUCCESS:
+                               strcpy(*pdo_err, "00000");
                                break;
-
-#if 0
-                       case 955:       /* ORA-00955: name is already used by an existing object */
-                               *pdo_err = PDO_ERR_ALREADY_EXISTS;
+                       case OCI_ERROR:
+                               OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: %s (%s:%d)", what, errbuf, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
                                break;
-#endif
-
-                       case 12154:     /* ORA-12154: TNS:could not resolve service name */
-                               strcpy(*pdo_err, "42S02");
+                       case OCI_SUCCESS_WITH_INFO:
+                               OCIErrorGet(err, (ub4)1, NULL, &einfo->errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_SUCCESS_WITH_INFO: %s (%s:%d)", what, errbuf, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
+                               break;
+                       case OCI_NEED_DATA:
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_NEED_DATA (%s:%d)", what, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
                                break;
-                               
-                       case 22:        /* ORA-00022: invalid session id */
-                       case 1012:      /* ORA-01012: */
-                       case 3113:      /* ORA-03133: end of file on communication channel */
-                       case 604:
-                       case 1041:
-                               /* consider the connection closed */
-                               dbh->is_closed = 1;
-                               H->attached = 0;
-                               strcpy(*pdo_err, "01002"); /* FIXME */
+                       case OCI_NO_DATA:
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_NO_DATA (%s:%d)", what, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
                                break;
+                       case OCI_INVALID_HANDLE:
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_INVALID_HANDLE (%s:%d)", what, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
+                               break;
+                       case OCI_STILL_EXECUTING:
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_STILL_EXECUTING (%s:%d)", what, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
+                               break;
+                       case OCI_CONTINUE:
+                               slprintf(tmp_buf, sizeof(tmp_buf), "%s: OCI_CONTINUE (%s:%d)", what, file, line);
+                               einfo->errmsg = pestrdup(tmp_buf, dbh->is_persistent);
+                               break;
+               }
+
+               if (einfo->errcode) {
+                       switch (einfo->errcode) {
+                               case 1013:      /* user requested cancel of current operation */
+                                       zend_bailout();
+                                       break;
 
-                       default:
-                               strcpy(*pdo_err, "HY000");
+#if 0
+                               case 955:       /* ORA-00955: name is already used by an existing object */
+                                       *pdo_err = PDO_ERR_ALREADY_EXISTS;
+                                       break;
+#endif
+
+                               case 12154:     /* ORA-12154: TNS:could not resolve service name */
+                                       strcpy(*pdo_err, "42S02");
+                                       break;
+
+                               case 22:        /* ORA-00022: invalid session id */
+                               case 1012:      /* ORA-01012: */
+                               case 3113:      /* ORA-03133: end of file on communication channel */
+                               case 604:
+                               case 1041:
+                                       /* consider the connection closed */
+                                       dbh->is_closed = 1;
+                                       H->attached = 0;
+                                       strcpy(*pdo_err, "01002"); /* FIXME */
+                                       break;
+
+                               default:
+                                       strcpy(*pdo_err, "HY000");
+                       }
                }
-       }
 
-       if (stmt) {
-               /* always propogate the error code back up to the dbh,
-                * so that we can catch the error information when execute
-                * is called via query.  See Bug #33707 */
-               if (H->einfo.errmsg) {
-                       pefree(H->einfo.errmsg, dbh->is_persistent);
+               if (stmt) {
+                       /* always propogate the error code back up to the dbh,
+                        * so that we can catch the error information when execute
+                        * is called via query.  See Bug #33707 */
+                       if (H->einfo.errmsg) {
+                               pefree(H->einfo.errmsg, dbh->is_persistent);
+                       }
+                       H->einfo = *einfo;
+                       H->einfo.errmsg = einfo->errmsg ? pestrdup(einfo->errmsg, dbh->is_persistent) : NULL;
+                       strcpy(dbh->error_code, stmt->error_code);
                }
-               H->einfo = *einfo;
-               H->einfo.errmsg = einfo->errmsg ? pestrdup(einfo->errmsg, dbh->is_persistent) : NULL;
-               strcpy(dbh->error_code, stmt->error_code);
        }
 
        /* little mini hack so that we can use this code from the dbh ctor */
@@ -176,7 +183,7 @@ ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, swor
 static int oci_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
 {
        pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
-       
+
        if (H->svc) {
                /* rollback any outstanding work */
                OCITransRollback(H->svc, H->err, 0);
@@ -191,7 +198,7 @@ static int oci_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
                OCIHandleFree(H->svc, OCI_HTYPE_SVCCTX);
                H->svc = NULL;
        }
-       
+
        if (H->server && H->attached) {
                H->last_err = OCIServerDetach(H->server, H->err, OCI_DEFAULT);
                if (H->last_err) {
@@ -212,12 +219,12 @@ static int oci_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
                OCIHandleFree(H->env, OCI_HTYPE_ENV);
                H->env = NULL;
        }
-       
+
        if (H->einfo.errmsg) {
                pefree(H->einfo.errmsg, dbh->is_persistent);
                H->einfo.errmsg = NULL;
        }
+
        pefree(H, dbh->is_persistent);
 
        return 0;
@@ -255,7 +262,7 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pd
                efree(S);
                return 0;
        }
-       
+
        /* create an OCI statement handle */
        OCIHandleAlloc(H->env, (dvoid*)&S->stmt, OCI_HTYPE_STMT, 0, NULL);
 
@@ -295,7 +302,7 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pd
                efree(nsql);
                nsql = NULL;
        }
-       
+
        return 1;
 }
 /* }}} */
@@ -316,7 +323,7 @@ static long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS
                OCIHandleFree(stmt, OCI_HTYPE_STMT);
                return -1;
        }
-       
+
        H->last_err = OCIAttrGet(stmt, OCI_HTYPE_STMT, &stmt_type, 0, OCI_ATTR_STMT_TYPE, H->err);
 
        if (stmt_type == OCI_STMT_SELECT) {
@@ -339,7 +346,7 @@ static long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS
        }
 
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
-       
+
        return ret;
 }
 /* }}} */
@@ -408,7 +415,7 @@ static int oci_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_
        } else {
                return 0;
        }
-       
+
 }
 /* }}} */
 
@@ -438,16 +445,22 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC
        };
 
        php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 2);
-       
+
        H = pecalloc(1, sizeof(*H), dbh->is_persistent);
        dbh->driver_data = H;
-       
+
        /* allocate an environment */
 #if HAVE_OCIENVNLSCREATE
        if (vars[0].optval) {
                H->charset = OCINlsCharSetNameToId(pdo_oci_Env, vars[0].optval);
-               if (H->charset) {
-                       OCIEnvNlsCreate(&H->env, PDO_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, H->charset, H->charset);
+               if (!H->charset) {
+                       oci_init_error("OCINlsCharSetNameToId: unknown character set name");
+                       goto cleanup;
+               } else {
+                       if (OCIEnvNlsCreate(&H->env, PDO_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, H->charset, H->charset) != OCI_SUCCESS) {
+                               oci_init_error("OCIEnvNlsCreate: Check the character set is valid and that PHP has access to Oracle libraries and NLS data");
+                               goto cleanup;
+                       }
                }
        }
 #endif
@@ -458,10 +471,10 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC
 
        /* something to hold errors */
        OCIHandleAlloc(H->env, (dvoid **)&H->err, OCI_HTYPE_ERROR, 0, NULL);
-       
+
        /* handle for the server */
        OCIHandleAlloc(H->env, (dvoid **)&H->server, OCI_HTYPE_SERVER, 0, NULL);
-       
+
        H->last_err = OCIServerAttach(H->server, H->err, (text*)vars[1].optval,
                        strlen(vars[1].optval), OCI_DEFAULT);
 
@@ -515,25 +528,25 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC
        }
 
        /* Now fire up the session */
-       H->last_err = OCISessionBegin(H->svc, H->err, H->session, OCI_CRED_RDBMS, OCI_DEFAULT); 
+       H->last_err = OCISessionBegin(H->svc, H->err, H->session, OCI_CRED_RDBMS, OCI_DEFAULT);
        if (H->last_err) {
-               oci_drv_error("OCISessionBegin:");
+               oci_drv_error("OCISessionBegin");
                goto cleanup;
        }
 
        /* set the server handle into service handle */
        H->last_err = OCIAttrSet(H->svc, OCI_HTYPE_SVCCTX, H->session, 0, OCI_ATTR_SESSION, H->err);
        if (H->last_err) {
-               oci_drv_error("OCIAttrSet: OCI_ATTR_SESSION:");
+               oci_drv_error("OCIAttrSet: OCI_ATTR_SESSION");
                goto cleanup;
        }
-       
+
        dbh->methods = &oci_methods;
        dbh->alloc_own_columns = 1;
        dbh->native_case = PDO_CASE_UPPER;
 
        ret = 1;
-       
+
 cleanup:
        for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
                if (vars[i].freeme) {
index fdd0cb7bb006e8431afd19b5bf11db5fe32f9ff1..963957fa13bc1015fddc22f144c8f296b98ecc29 100755 (executable)
 #include "Zend/zend_extensions.h"
 
 #define STMT_CALL(name, params)        \
-       S->last_err = name params; \
-       S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, __FILE__, __LINE__ TSRMLS_CC); \
-       if (S->last_err) { \
-               return 0; \
-       }
+       do { \
+               S->last_err = name params;                                                                              \
+               S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC); \
+               if (S->last_err) {                                                                                              \
+                       return 0;                                                                                                       \
+               }                                                                                                                               \
+       } while(0)
 
 #define STMT_CALL_MSG(name, msg, params)       \
-       S->last_err = name params; \
-       S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, __FILE__, __LINE__ TSRMLS_CC); \
-       if (S->last_err) { \
-               return 0; \
-       }
+       do { \
+               S->last_err = name params;                                                                              \
+               S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC); \
+               if (S->last_err) {                                                                                              \
+                       return 0;                                                                                                       \
+               }                                                                                                                               \
+       } while(0)
 
 static php_stream *oci_create_lob_stream(pdo_stmt_t *stmt, OCILobLocator *lob TSRMLS_DC);
 
@@ -52,7 +56,7 @@ static int oci_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
        pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
        HashTable *BC = stmt->bound_columns;
        HashTable *BP = stmt->bound_params;
-       
+
        int i;
 
        if (S->stmt) {
@@ -75,18 +79,18 @@ static int oci_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
                FREE_HASHTABLE(stmt->bound_columns);
                stmt->bound_columns = NULL;
        }
-       
+
        if (BP) {
                zend_hash_destroy(BP);
                FREE_HASHTABLE(stmt->bound_params);
                stmt->bound_params = NULL;
        }
-       
+
        if (S->einfo.errmsg) {
                efree(S->einfo.errmsg);
                S->einfo.errmsg = NULL;
        }
-       
+
        if (S->cols) {
                for (i = 0; i < stmt->column_count; i++) {
                        if (S->cols[i].data) {
@@ -150,7 +154,7 @@ static int oci_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
                                (S->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));
 
                stmt->column_count = (int)colcount;
-       
+
                if (S->cols) {
                        int i;
                        for (i = 0; i < stmt->column_count; i++) {
@@ -170,7 +174,7 @@ static int oci_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
 
                S->cols = ecalloc(colcount, sizeof(pdo_oci_column));
        }
-       
+
        STMT_CALL_MSG(OCIAttrGet, "ATTR_ROW_COUNT",
                        (S->stmt, OCI_HTYPE_STMT, &rowcount, 0, OCI_ATTR_ROW_COUNT, S->err));
        stmt->row_count = (long)rowcount;
@@ -188,7 +192,7 @@ static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dv
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen");
                return OCI_ERROR;
        }
-       
+
        *indpp = &P->indicator;
 
        if (P->thing) {
@@ -229,8 +233,8 @@ static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, d
                *rcodepp = &P->retcode;
                *indpp = &P->indicator;
                return OCI_CONTINUE;
-       } 
-       
+       }
+
        if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
                return OCI_CONTINUE;
        }
@@ -242,7 +246,7 @@ static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, d
        Z_STRVAL_P(param->parameter) = ecalloc(1, Z_STRLEN_P(param->parameter)+1);
        P->used_for_output = 1;
 
-       P->actual_len = Z_STRLEN_P(param->parameter);   
+       P->actual_len = Z_STRLEN_P(param->parameter);
        *alenpp = &P->actual_len;
        *bufpp = Z_STRVAL_P(param->parameter);
        *piecep = OCI_ONE_PIECE;
@@ -260,7 +264,7 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
        if (param->is_param) {
                pdo_oci_bound_param *P;
                sb4 value_sz = -1;
-               
+
                P = (pdo_oci_bound_param*)param->driver_data;
 
                switch (event_type) {
@@ -274,7 +278,7 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
                        case PDO_PARAM_EVT_ALLOC:
                                P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
                                param->driver_data = P;
-                       
+
                                /* figure out what we're doing */
                                switch (PDO_PARAM_TYPE(param->param_type)) {
                                        case PDO_PARAM_STMT:
@@ -293,9 +297,9 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
                                                if (param->max_value_len == 0) {
                                                        value_sz = 1332; /* maximum size before value is interpreted as a LONG value */
                                                }
-                                               
+
                                }
-                               
+
                                if (param->name) {
                                        STMT_CALL(OCIBindByName, (S->stmt,
                                                        &P->bind, S->err, (text*)param->name,
@@ -309,7 +313,7 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
                                                        &P->indicator, 0, &P->retcode, 0, 0,
                                                        OCI_DATA_AT_EXEC));
                                }
-                       
+
                                STMT_CALL(OCIBindDynamic, (P->bind,
                                                        S->err,
                                                        param, oci_bind_input_cb,
@@ -421,7 +425,7 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
                                return 1;
                }
        }
-       
+
        return 1;
 } /* }}} */
 
@@ -459,7 +463,7 @@ static int oci_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, long
        if (S->last_err == OCI_SUCCESS_WITH_INFO || S->last_err == OCI_SUCCESS) {
                return 1;
        }
-       
+
        oci_stmt_error("OCIStmtFetch");
 
        return 0;
@@ -528,7 +532,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
        col->name = estrndup(colname, namelen);
 
        S->cols[colno].dtype = dtype;
-       
+
        /* how much room do we need to store the field */
        switch (dtype) {
                case SQLT_LBI:
@@ -550,7 +554,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
                        S->cols[colno].datalen = sizeof(OCILobLocator*);
                        dyn = TRUE;
                        break;
-                                                                                                                                                                                                                                                               
+
                case SQLT_BIN:
                default:
                        if (dtype == SQLT_DAT || dtype == SQLT_NUM
@@ -588,7 +592,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
                STMT_CALL(OCIDefineDynamic, (S->cols[colno].def, S->err, &S->cols[colno],
                                oci_define_callback));
        }
-       
+
        return 1;
 } /* }}} */
 
@@ -614,7 +618,7 @@ static size_t oci_blob_write(php_stream *stream, const char *buf, size_t count T
        if (r != OCI_SUCCESS) {
                return (size_t)-1;
        }
-       
+
        self->offset += amt;
        return amt;
 }
@@ -665,7 +669,7 @@ static int oci_blob_seek(php_stream *stream, off_t offset, int whence, off_t *ne
 {
        struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
 
-       return -1;      
+       return -1;
 }
 */
 
@@ -723,7 +727,7 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned lo
                        *len = 0;
                        return *ptr ? 1 : 0;
                }
-               
+
                *ptr = C->data;
                *len = C->fetched_len;
                return 1;
index 9e0c4a470ddb1a6608d4d078a08ef21a74382071..2aaafd0853b557c6896264e1a885a59f696ac0bf 100755 (executable)
@@ -86,9 +86,10 @@ extern const ub4 PDO_OCI_INIT_MODE;
 extern pdo_driver_t pdo_oci_driver;
 extern OCIEnv *pdo_oci_Env;
 
-ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, const char *file, int line TSRMLS_DC);
-#define oci_drv_error(w)       _oci_error(H->err, dbh, NULL, w, H->last_err, __FILE__, __LINE__ TSRMLS_CC)
-#define oci_stmt_error(w)      _oci_error(S->err, stmt->dbh, stmt, w, S->last_err, __FILE__, __LINE__ TSRMLS_CC)
+ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, sword status, int isinit, const char *file, int line TSRMLS_DC);
+#define oci_init_error(w)      _oci_error(H->err, dbh, NULL, w, H->last_err, TRUE, __FILE__, __LINE__ TSRMLS_CC)
+#define oci_drv_error(w)       _oci_error(H->err, dbh, NULL, w, H->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC)
+#define oci_stmt_error(w)      _oci_error(S->err, stmt->dbh, stmt, w, S->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC)
 
 extern struct pdo_stmt_methods oci_stmt_methods;
 
diff --git a/ext/pdo_oci/tests/pecl_bug_11345.phpt b/ext/pdo_oci/tests/pecl_bug_11345.phpt
new file mode 100644 (file)
index 0000000..b80773a
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+PECL PDO_OCI Bug #11345 (Test invalid character set name)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
+require(dirname(__FILE__).'/../../pdo/tests/pdo_test.inc');
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+// This tests only part of PECL bug 11345.  The other part - testing
+// when the National Language Support (NLS) environment can't be
+// initialized - is very difficult to test portably.
+
+try {
+    $dbh = new PDO('oci:dbname=xxx;charset=yyy', 'abc', 'def');
+} 
+catch (PDOException $e) {
+    echo 'Connection failed: ' . $e->getMessage(). "\n";
+    exit;
+}
+
+echo "Done\n";
+
+?>
+
+--EXPECTF--
+Connection failed: SQLSTATE[HY000]: OCINlsCharSetNameToId: unknown character set name (%s)
\ No newline at end of file