mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
PECL Bug #16035 (oci_connect without ORACLE_HOME defined causes segfault)
This commit is contained in:
parent
f8996c4b6c
commit
c7438c63f0
6 changed files with 139 additions and 95 deletions
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
|
#define ONUPDATELONGFUNC OnUpdateInt
|
||||||
#endif
|
#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 protos {{{ */
|
||||||
static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
|
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);
|
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)
|
static void php_oci_init_global_handles(TSRMLS_D)
|
||||||
{
|
{
|
||||||
sword errcode;
|
sword errstatus;
|
||||||
sb4 error_code = 0;
|
sb4 ora_error_code = 0;
|
||||||
text tmp_buf[PHP_OCI_ERRBUF_LEN];
|
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) {
|
if (errstatus == OCI_ERROR) {
|
||||||
goto 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");
|
||||||
errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
|
# 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");
|
||||||
if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) {
|
# endif
|
||||||
goto oci_error;
|
#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");
|
||||||
|
|
||||||
#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));
|
|
||||||
#endif
|
#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 (ora_error_code) {
|
||||||
|
int tmp_buf_len = strlen((char *)tmp_buf);
|
||||||
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 (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);
|
||||||
if (errcode != OCI_SUCCESS_WITH_INFO) {
|
} else {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf);
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_ERROR: %s", tmp_buf);
|
||||||
|
|
||||||
OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
|
OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
|
||||||
|
|
||||||
OCI_G(env) = NULL;
|
OCI_G(env) = NULL;
|
||||||
OCI_G(err) = NULL;
|
OCI_G(err) = NULL;
|
||||||
} else {
|
}
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
@ -926,14 +937,6 @@ PHP_MINIT_FUNCTION(oci)
|
||||||
zend_class_entry oci_lob_class_entry;
|
zend_class_entry oci_lob_class_entry;
|
||||||
zend_class_entry oci_coll_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();
|
REGISTER_INI_ENTRIES();
|
||||||
|
|
||||||
le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
|
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
|
/* We cannot use the new session create logic (OCISessionGet from
|
||||||
* client-side session pool) when privileged connect or password
|
* client-side session pool) when privileged connect or password
|
||||||
* change is attempted or OCI_CRED_EXT mode is specified. TODO:
|
* 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);
|
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 (!UG(unicode)) {
|
||||||
if (charset.s && *charset.s) {
|
if (charset.s && *charset.s) {
|
||||||
PHP_OCI_CALL_RETURN(charsetid, OCINlsCharSetNameToId, (OCI_G(env), (CONST oratext *)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)
|
oci_connect() without ORACLE_HOME set (OCIServerAttach() segfaults)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
/* disabled for a while */
|
|
||||||
die("skip");
|
|
||||||
|
|
||||||
if (!extension_loaded('oci8')) die("skip no oci8 extension");
|
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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require dirname(__FILE__)."/connect.inc";
|
require dirname(__FILE__)."/details.inc";
|
||||||
|
|
||||||
|
putenv('ORACLE_HOME=""');
|
||||||
|
|
||||||
if (!empty($dbase)) {
|
if (!empty($dbase)) {
|
||||||
var_dump(oci_connect($user, $password, $dbase));
|
var_dump(oci_connect($user, $password, $dbase));
|
||||||
|
@ -19,12 +27,10 @@ else {
|
||||||
var_dump(oci_connect($user, $password));
|
var_dump(oci_connect($user, $password));
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Done\n";
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
===DONE===
|
||||||
|
<?php exit(0); ?>
|
||||||
--EXPECTF--
|
--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(): 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
|
||||||
|
|
||||||
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
|
|
||||||
bool(false)
|
bool(false)
|
||||||
Done
|
===DONE===
|
||||||
|
|
|
@ -2,14 +2,23 @@
|
||||||
ocilogon() without ORACLE_HOME set (OCIServerAttach() segfaults)
|
ocilogon() without ORACLE_HOME set (OCIServerAttach() segfaults)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
/* disabled for a while */
|
|
||||||
die("skip");
|
|
||||||
if (!extension_loaded('oci8')) die("skip no oci8 extension");
|
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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require dirname(__FILE__)."/connect.inc";
|
require dirname(__FILE__)."/details.inc";
|
||||||
|
|
||||||
|
putenv('ORACLE_HOME=""');
|
||||||
|
|
||||||
if (!empty($dbase)) {
|
if (!empty($dbase)) {
|
||||||
var_dump(ocilogon($user, $password, $dbase));
|
var_dump(ocilogon($user, $password, $dbase));
|
||||||
|
@ -18,12 +27,10 @@ else {
|
||||||
var_dump(ocilogon($user, $password));
|
var_dump(ocilogon($user, $password));
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Done\n";
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
===DONE===
|
||||||
|
<?php exit(0); ?>
|
||||||
--EXPECTF--
|
--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: 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
|
||||||
|
|
||||||
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
|
|
||||||
bool(false)
|
bool(false)
|
||||||
Done
|
===DONE===
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
if ($c) {
|
if ($c) {
|
||||||
$ora_sql = "DROP TABLE
|
$ora_sql = "DROP TABLE ".$schema.$table_name;
|
||||||
".$schema.$table_name."
|
$statement = oci_parse($c, $ora_sql);
|
||||||
";
|
@oci_execute($statement);
|
||||||
|
|
||||||
$statement = OCIParse($c, $ora_sql);
|
$ora_sql = "CREATE TABLE ".$schema.$table_name." (id NUMBER, value NUMBER, blob BLOB, clob CLOB, string VARCHAR(10))";
|
||||||
@OCIExecute($statement);
|
$statement = oci_parse($c, $ora_sql);
|
||||||
|
oci_execute($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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -32,12 +32,18 @@ if (false !== getenv('PHP_OCI8_TEST_DB')) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$user = "system";
|
$user = "system";
|
||||||
$password = "system";
|
$password = "oracle";
|
||||||
$dbase = "localhost/XE";
|
$dbase = "localhost/XE";
|
||||||
$oracle_on_localhost = TRUE;
|
$oracle_on_localhost = TRUE;
|
||||||
$test_drcp = FALSE;
|
$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
|
* 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…
Add table
Add a link
Reference in a new issue