mirror of
https://github.com/php/php-src.git
synced 2024-09-25 20:07:26 +00:00
PECL Bug #16035 (oci_connect without ORACLE_HOME defined causes segfault)
This commit is contained in:
parent
f8996c4b6c
commit
c7438c63f0
128
ext/oci8/oci8.c
128
ext/oci8/oci8.c
@ -72,6 +72,12 @@ zend_class_entry *oci_coll_class_entry_ptr;
|
||||
#define ONUPDATELONGFUNC OnUpdateInt
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT | OCI_THREADED | OCI_NO_MUTEX)
|
||||
#else
|
||||
#define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT)
|
||||
#endif
|
||||
|
||||
/* static protos {{{ */
|
||||
static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
|
||||
static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
|
||||
@ -836,60 +842,65 @@ PHP_INI_END()
|
||||
*/
|
||||
static void php_oci_init_global_handles(TSRMLS_D)
|
||||
{
|
||||
sword errcode;
|
||||
sb4 error_code = 0;
|
||||
text tmp_buf[PHP_OCI_ERRBUF_LEN];
|
||||
sword errstatus;
|
||||
sb4 ora_error_code = 0;
|
||||
text tmp_buf[PHP_OCI_ERRBUF_LEN];
|
||||
|
||||
errcode = OCIEnvNlsCreate(&OCI_G(env), OCI_DEFAULT, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
|
||||
errstatus = OCIEnvNlsCreate(&OCI_G(env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
|
||||
|
||||
if (errcode == OCI_ERROR) {
|
||||
goto oci_error;
|
||||
}
|
||||
|
||||
errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
|
||||
|
||||
if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) {
|
||||
goto oci_error;
|
||||
}
|
||||
|
||||
#if !defined(OCI_MAJOR_VERSION) || (OCI_MAJOR_VERSION < 11)
|
||||
/* This works around PECL bug #15988 (sqlnet.ora not being read).
|
||||
* The root cause was fixed in Oracle 10.2.0.4 but there is no
|
||||
* compile time method to check for that precise patch level, nor
|
||||
* can it be guaranteed that runtime will use the same patch level
|
||||
* the code was compiled with. So, we do this code for all non
|
||||
* 11g versions.
|
||||
*/
|
||||
OCICPool *cpoolh;
|
||||
ub4 cpoolmode = 0x80000000; /* Pass invalid mode to OCIConnectionPoolCreate */
|
||||
PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **) &cpoolh, OCI_HTYPE_CPOOL, (size_t) 0, (dvoid **) 0));
|
||||
PHP_OCI_CALL(OCIConnectionPoolCreate, (OCI_G(env), OCI_G(err), cpoolh, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, NULL, 0, cpoolmode));
|
||||
PHP_OCI_CALL(OCIConnectionPoolDestroy, (cpoolh, OCI_G(err), OCI_DEFAULT));
|
||||
PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL));
|
||||
if (errstatus == OCI_ERROR) {
|
||||
#ifdef HAVE_OCI_INSTANT_CLIENT
|
||||
# ifdef PHP_WIN32
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that PATH includes the directory with Oracle Instant Client libraries");
|
||||
# else
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that LD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries");
|
||||
# endif
|
||||
#else
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory");
|
||||
#endif
|
||||
OCI_G(env) = NULL;
|
||||
OCI_G(err) = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
errstatus = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
|
||||
|
||||
oci_error:
|
||||
if (errstatus == OCI_SUCCESS) {
|
||||
#if !defined(OCI_MAJOR_VERSION) || (OCI_MAJOR_VERSION < 11)
|
||||
/* This fixes PECL bug 15988 (sqlnet.ora not being read). The
|
||||
* root cause was fixed in Oracle 10.2.0.4 but there is no
|
||||
* compile time method to check for that precise patch level,
|
||||
* nor can it be guaranteed that runtime will use the same
|
||||
* patch level the code was compiled with. So, we do this
|
||||
* code for all non 11g versions.
|
||||
*/
|
||||
OCICPool *cpoolh;
|
||||
ub4 cpoolmode = 0x80000000; /* Pass invalid mode to OCIConnectionPoolCreate */
|
||||
PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **) &cpoolh, OCI_HTYPE_CPOOL, (size_t) 0, (dvoid **) 0));
|
||||
PHP_OCI_CALL(OCIConnectionPoolCreate, (OCI_G(env), OCI_G(err), cpoolh, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, NULL, 0, cpoolmode));
|
||||
PHP_OCI_CALL(OCIConnectionPoolDestroy, (cpoolh, OCI_G(err), OCI_DEFAULT));
|
||||
PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL));
|
||||
#endif
|
||||
} else {
|
||||
OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
|
||||
|
||||
OCIErrorGet(OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
|
||||
|
||||
if (error_code) {
|
||||
int tmp_buf_len = strlen((char *)tmp_buf);
|
||||
|
||||
if (tmp_buf_len > 0 && tmp_buf[tmp_buf_len - 1] == '\n') {
|
||||
tmp_buf[tmp_buf_len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (errcode != OCI_SUCCESS_WITH_INFO) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf);
|
||||
|
||||
OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
|
||||
|
||||
OCI_G(env) = NULL;
|
||||
OCI_G(err) = NULL;
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
|
||||
if (ora_error_code) {
|
||||
int tmp_buf_len = strlen((char *)tmp_buf);
|
||||
|
||||
if (tmp_buf_len > 0 && tmp_buf[tmp_buf_len - 1] == '\n') {
|
||||
tmp_buf[tmp_buf_len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (errstatus == OCI_SUCCESS_WITH_INFO) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_ERROR: %s", tmp_buf);
|
||||
|
||||
OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
|
||||
|
||||
OCI_G(env) = NULL;
|
||||
OCI_G(err) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
@ -926,14 +937,6 @@ PHP_MINIT_FUNCTION(oci)
|
||||
zend_class_entry oci_lob_class_entry;
|
||||
zend_class_entry oci_coll_class_entry;
|
||||
|
||||
#define PHP_OCI_INIT_MODE_TMP OCI_DEFAULT | OCI_OBJECT
|
||||
|
||||
#ifdef ZTS
|
||||
#define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP | OCI_THREADED
|
||||
#else
|
||||
#define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP
|
||||
#endif
|
||||
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
|
||||
@ -1565,6 +1568,14 @@ php_oci_connection *php_oci_do_connect_ex(zstr username, int username_len, zstr
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize global handles if they weren't initialized before */
|
||||
if (OCI_G(env) == NULL) {
|
||||
php_oci_init_global_handles(TSRMLS_C);
|
||||
if (OCI_G(env) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* We cannot use the new session create logic (OCISessionGet from
|
||||
* client-side session pool) when privileged connect or password
|
||||
* change is attempted or OCI_CRED_EXT mode is specified. TODO:
|
||||
@ -1601,11 +1612,6 @@ php_oci_connection *php_oci_do_connect_ex(zstr username, int username_len, zstr
|
||||
}
|
||||
smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
|
||||
|
||||
/* Initialize global handles if they weren't initialized before */
|
||||
if (OCI_G(env) == NULL) {
|
||||
php_oci_init_global_handles(TSRMLS_C);
|
||||
}
|
||||
|
||||
if (!UG(unicode)) {
|
||||
if (charset.s && *charset.s) {
|
||||
PHP_OCI_CALL_RETURN(charsetid, OCINlsCharSetNameToId, (OCI_G(env), (CONST oratext *)charset.s));
|
||||
|
@ -2,15 +2,23 @@
|
||||
oci_connect() without ORACLE_HOME set (OCIServerAttach() segfaults)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
/* disabled for a while */
|
||||
die("skip");
|
||||
|
||||
if (!extension_loaded('oci8')) die("skip no oci8 extension");
|
||||
/* Disabled: Fix for PECL Bug #16035 stops a crash if ORACLE_HOME is not set when PHP starts. Using putenv('ORACLE_HOME=""') at runtime will still segfault */
|
||||
die("skip can't be tested with run-tests.php");
|
||||
ob_start();
|
||||
phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_clean();
|
||||
$ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo);
|
||||
if ($ov !== 1) {
|
||||
die ("skip Test only valid when OCI8 is built with an ORACLE_HOME");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
require dirname(__FILE__)."/details.inc";
|
||||
|
||||
putenv('ORACLE_HOME=""');
|
||||
|
||||
if (!empty($dbase)) {
|
||||
var_dump(oci_connect($user, $password, $dbase));
|
||||
@ -19,12 +27,10 @@ else {
|
||||
var_dump(oci_connect($user, $password));
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
Warning: ocilogon(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect.inc on line %d
|
||||
|
||||
Warning: oci_connect(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect_without_oracle_home.php on line %d
|
||||
Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
===DONE===
|
||||
|
@ -2,14 +2,23 @@
|
||||
ocilogon() without ORACLE_HOME set (OCIServerAttach() segfaults)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
/* disabled for a while */
|
||||
die("skip");
|
||||
if (!extension_loaded('oci8')) die("skip no oci8 extension");
|
||||
/* Disabled: Fix for PECL Bug #16035 stops a crash if ORACLE_HOME is not set when PHP starts. Using putenv('ORACLE_HOME=""') at runtime will still segfault */
|
||||
die("skip can't be tested with run-tests.php");
|
||||
ob_start();
|
||||
phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_clean();
|
||||
$ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo);
|
||||
if ($ov !== 1) {
|
||||
die ("skip Test only valid when OCI8 is built with an ORACLE_HOME");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
require dirname(__FILE__)."/details.inc";
|
||||
|
||||
putenv('ORACLE_HOME=""');
|
||||
|
||||
if (!empty($dbase)) {
|
||||
var_dump(ocilogon($user, $password, $dbase));
|
||||
@ -18,12 +27,10 @@ else {
|
||||
var_dump(ocilogon($user, $password));
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
Warning: ocilogon(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect.inc on line %d
|
||||
|
||||
Warning: oci_connect(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect_without_oracle_home.php on line %d
|
||||
Warning: ocilogon(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
===DONE===
|
||||
|
@ -1,19 +1,11 @@
|
||||
<?php
|
||||
|
||||
if ($c) {
|
||||
$ora_sql = "DROP TABLE
|
||||
".$schema.$table_name."
|
||||
";
|
||||
$ora_sql = "DROP TABLE ".$schema.$table_name;
|
||||
$statement = oci_parse($c, $ora_sql);
|
||||
@oci_execute($statement);
|
||||
|
||||
$statement = OCIParse($c, $ora_sql);
|
||||
@OCIExecute($statement);
|
||||
|
||||
$ora_sql = "CREATE TABLE
|
||||
".$schema.$table_name." (id NUMBER, value NUMBER, blob BLOB, clob CLOB, string VARCHAR(10))
|
||||
";
|
||||
|
||||
$statement = OCIParse($c,$ora_sql);
|
||||
OCIExecute($statement);
|
||||
$ora_sql = "CREATE TABLE ".$schema.$table_name." (id NUMBER, value NUMBER, blob BLOB, clob CLOB, string VARCHAR(10))";
|
||||
$statement = oci_parse($c, $ora_sql);
|
||||
oci_execute($statement);
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -32,12 +32,18 @@ if (false !== getenv('PHP_OCI8_TEST_DB')) {
|
||||
}
|
||||
} else {
|
||||
$user = "system";
|
||||
$password = "system";
|
||||
$password = "oracle";
|
||||
$dbase = "localhost/XE";
|
||||
$oracle_on_localhost = TRUE;
|
||||
$test_drcp = FALSE;
|
||||
}
|
||||
|
||||
$user = "system";
|
||||
$password = "oracle";
|
||||
$dbase = "ca-tools1.us.oracle.com/orcl";
|
||||
$oracle_on_localhost = TRUE;
|
||||
$test_drcp = FALSE;
|
||||
|
||||
/*
|
||||
* Common object names for scripts to use
|
||||
*/
|
||||
|
27
ext/oci8/tests/pecl_bug16035.phpt
Normal file
27
ext/oci8/tests/pecl_bug16035.phpt
Normal file
@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
PECL Bug #16035 (Crash with Oracle 10.2 connecting with a character set but ORACLE_HOME isn't set)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('oci8')) die ("skip no oci8 extension");
|
||||
/* Disabled: Fix for PECL Bug #16035 stops a crash if ORACLE_HOME is not set when PHP starts. Using putenv('ORACLE_HOME=""') at runtime will still segfault */
|
||||
die("skip can't be tested with run-tests.php");
|
||||
ob_start();
|
||||
phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_clean();
|
||||
$ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo);
|
||||
if ($ov !== 1) {
|
||||
die ("skip Test only valid when OCI8 is built with an ORACLE_HOME");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
putenv('ORACLE_HOME=""');
|
||||
oci_connect('abc', 'def', 'ghi', 'jkl');
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
PHP Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory in %s on line %d
|
||||
===DONE===
|
Loading…
Reference in New Issue
Block a user