php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57706 Seg fault after NLS environment initialization error
Submitted: 2007-06-18 03:37 UTC Modified: 2007-07-03 00:10 UTC
From: christopher dot jones at oracle dot com Assigned:
Status: Closed Package: PDO_OCI (PECL)
PHP Version: 5_2 CVS-2007-06-18 OS: Linux x86
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: christopher dot jones at oracle dot com
New email:
PHP Version: OS:

 

 [2007-06-18 03:37 UTC] christopher dot jones at oracle dot com
Description:
------------
Ben Ramsey & Maggie Nelson reported a problem caused by PDO_OCI failing because it did not have access to Oracle NLS data.

Here is a patch to report errors (i) when the character set name is invalid (ii) when the NLS environment can't be initialized.

Reproduce code:
---------------
For (i): $dbh = new PDO('oci:dbname=localhost/XE;charset=XYZ', 'hr', 'hrpwd');

For (ii) when on Linux using Oracle Instant Client 10.2.0.3 libraries: $dbh = new PDO('oci:dbname=localhost/XE;charset=TR8MACTURKISH', 'hr', 'hrpwd');

The proposed patch is:

--- oci_driver.c.orig	2007-06-17 20:02:31.000000000 -0700
+++ oci_driver.c	2007-06-17 23:59:46.000000000 -0700
@@ -55,7 +55,7 @@
 }
 /* }}} */

-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 init, const char *file, int line TSRMLS_DC) /* {{{ */
 {
 	text errbuf[1024] = "<<Unknown>>";
 	char tmp_buf[2048];
@@ -84,6 +84,11 @@
 	einfo->file = file;
 	einfo->line = line;

+	if (init) { /* 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");
@@ -163,6 +168,7 @@
 		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 */
 	if (!dbh->methods) {
@@ -446,8 +452,14 @@
 #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
@@ -517,14 +529,14 @@
 	/* Now fire up the session */
 	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;
 	}

--- oci_statement.c.orig	2007-01-26 07:07:45.000000000 -0800
+++ oci_statement.c	2007-06-17 23:59:46.000000000 -0700
@@ -33,14 +33,14 @@

 #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); \
+	S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, 0, __FILE__, __LINE__ TSRMLS_CC); \
 	if (S->last_err) { \
 		return 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); \
+	S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, 0, __FILE__, __LINE__ TSRMLS_CC); \
 	if (S->last_err) { \
 		return 0; \
 	}

--- php_pdo_oci_int.h.orig	2007-01-01 01:36:05.000000000 -0800
+++ php_pdo_oci_int.h	2007-06-17 23:53:06.000000000 -0700
@@ -86,9 +86,10 @@
 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 init, const char *file, int line TSRMLS_DC);
+#define oci_init_error(w)	_oci_error(H->err, dbh, NULL, w, H->last_err, 1, __FILE__, __LINE__ TSRMLS_CC)
+#define oci_drv_error(w)	_oci_error(H->err, dbh, NULL, w, H->last_err, 0, __FILE__, __LINE__ TSRMLS_CC)
+#define oci_stmt_error(w)	_oci_error(S->err, stmt->dbh, stmt, w, S->last_err, 0, __FILE__, __LINE__ TSRMLS_CC)

 extern struct pdo_stmt_methods oci_stmt_methods;




Expected result:
----------------
For (i) the message should be:
Connection failed: SQLSTATE[HY000]: OCINlsCharSetNameToId: unknown character set name (/home/cjones/phpsrc/php5/ext/pdo_oci/oci_driver.c:456)

For (ii) the message should be:
Connection failed: SQLSTATE[HY000]: OCIEnvNlsCreate: Check the character set is valid and that PHP has access to Oracle libraries and NLS data (/home/cjones/phpsrc/php5/ext/pdo_oci/oci_driver.c:461)


Actual result:
--------------
For (i) the invalid character set is ignored

For (ii) Segmentation fault (core dumped)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-07-03 00:10 UTC] christopher dot jones at oracle dot com
This bug has been fixed in CVS.

In case this was a documentation problem, the fix will show up at the
end of next Sunday (CET) on pecl.php.net.

In case this was a pecl.php.net website problem, the change will show
up on the website in short time.
 
Thank you for the report, and for helping us make PECL better.

------------------
Fixed in PHP 5.2.4
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Sep 16 00:01:27 2019 UTC