]> granicus.if.org Git - php/commitdiff
More PHP7 compat (Rajendra/Senthil)
authorChristopher Jones <christopher.jones@oracle.com>
Thu, 30 Jul 2015 10:25:40 +0000 (20:25 +1000)
committerChristopher Jones <christopher.jones@oracle.com>
Thu, 30 Jul 2015 10:25:40 +0000 (20:25 +1000)
ext/oci8/oci8.c
ext/oci8/oci8_interface.c
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h

index 2c65ea94f9e6872e7e98cb9edc9d23e933aa0290..9eae15e346b541482266454cd98d251841bf27eb 100644 (file)
@@ -100,13 +100,6 @@ zend_class_entry *oci_coll_class_entry_ptr;
 #define SQLT_CFILEE 115
 #endif
 
-#ifdef OCI_ERROR_MAXMSG_SIZE2
-/* Bigger size is defined from 11.2.0.3 onwards */
-#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE2
-#else
-#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE
-#endif
-
 #if ZEND_MODULE_API_NO > 20020429
 #define ONUPDATELONGFUNC OnUpdateLong
 #else
@@ -1084,7 +1077,7 @@ static void php_oci_init_global_handles(void)
 {
        sword errstatus;
        sb4   ora_error_code = 0;
-       text  tmp_buf[OCI_ERROR_MAXMSG_SIZE];  /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
+       text  tmp_buf[PHP_OCI_ERRBUF_LEN];  /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
 
        errstatus = OCIEnvNlsCreate(&OCI_G(env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
 
@@ -1095,7 +1088,7 @@ static void php_oci_init_global_handles(void)
                php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
 #endif
                if (OCI_G(env)
-                       && OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
+                       && OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
                        && *tmp_buf) {
                        php_error_docref(NULL, E_WARNING, "%s", tmp_buf);
                }
@@ -1124,7 +1117,7 @@ static void php_oci_init_global_handles(void)
                PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL));
 #endif
        } else {
-               OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR);
+               OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_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);
@@ -1334,7 +1327,7 @@ PHP_MINFO_FUNCTION(oci)
 {
        char buf[32];
 #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
-       char *ver;
+       char ver[256];
 #endif
 
        php_info_print_table_start();
@@ -1348,9 +1341,8 @@ PHP_MINFO_FUNCTION(oci)
        php_info_print_table_row(2, "Revision", "$Id$");
 
 #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
-       php_oci_client_get_version(&ver);
+       php_oci_client_get_version(ver, sizeof(ver));
        php_info_print_table_row(2, "Oracle Run-time Client Library Version", ver);
-       efree(ver);
 #else
        php_info_print_table_row(2, "Oracle Run-time Client Library Version", "Unknown");
 #endif
@@ -1536,8 +1528,6 @@ void php_oci_define_hash_dtor(zval *data)
 {
        php_oci_define *define = (php_oci_define *) Z_PTR_P(data);
 
-       zval_ptr_dtor(define->zval);
-
        if (define->name) {
                efree(define->name);
                define->name = NULL;
@@ -1557,18 +1547,20 @@ void php_oci_bind_hash_dtor(zval *data)
 
        if (bind->array.elements) {
                efree(bind->array.elements);
+               bind->array.elements = NULL;
        }
 
        if (bind->array.element_lengths) {
                efree(bind->array.element_lengths);
+               bind->array.element_lengths = NULL;
        }
 
        if (bind->array.indicators) {
                efree(bind->array.indicators);
+               bind->array.indicators = NULL;
        }
 
        efree(bind);
-       zval_ptr_dtor(bind->zval);
 }
 /* }}} */
 
@@ -1585,7 +1577,10 @@ void php_oci_column_hash_dtor(zval *data)
        }
 
        if (column->descid) {
-               zend_list_close(column->descid);
+               if (GC_REFCOUNT(column->descid) == 1)
+                       zend_list_close(column->descid);
+               else
+                       GC_REFCOUNT(column->descid)--;
        }
 
        if (column->data) {
@@ -1638,17 +1633,16 @@ void php_oci_connection_descriptors_free(php_oci_connection *connection)
  */
 sb4 php_oci_error(OCIError *err_p, sword errstatus)
 {
-       text *errbuf = (text *)NULL;
+       text errbuf[PHP_OCI_ERRBUF_LEN];
        sb4 errcode = 0; /* Oracle error number */
 
        switch (errstatus) {
                case OCI_SUCCESS:
                        break;
                case OCI_SUCCESS_WITH_INFO:
-                       errcode = php_oci_fetch_errmsg(err_p, &errbuf);
-                       if (errbuf) {
+                       errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf));
+                       if (errcode) {
                                php_error_docref(NULL, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf);
-                               efree(errbuf);
                        } else {
                                php_error_docref(NULL, E_WARNING, "OCI_SUCCESS_WITH_INFO: failed to fetch error message");
                        }
@@ -1657,19 +1651,17 @@ sb4 php_oci_error(OCIError *err_p, sword errstatus)
                        php_error_docref(NULL, E_WARNING, "OCI_NEED_DATA");
                        break;
                case OCI_NO_DATA:
-                       errcode = php_oci_fetch_errmsg(err_p, &errbuf);
-                       if (errbuf) {
+                       errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf));
+                       if (errcode) {
                                php_error_docref(NULL, E_WARNING, "%s", errbuf);
-                               efree(errbuf);
                        } else {
                                php_error_docref(NULL, E_WARNING, "OCI_NO_DATA: failed to fetch error message");
                        }
                        break;
                case OCI_ERROR:
-                       errcode = php_oci_fetch_errmsg(err_p, &errbuf);
-                       if (errbuf) {
-                               php_error_docref(NULL, E_WARNING, "%s", errbuf);
-                               efree(errbuf);
+                       errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf));
+                       if (errcode) {
+                               php_error_docref(NULL, E_WARNING, "%s", errbuf, sizeof(errbuf));
                        } else {
                                php_error_docref(NULL, E_WARNING, "failed to fetch error message");
                        }
@@ -1702,24 +1694,17 @@ sb4 php_oci_error(OCIError *err_p, sword errstatus)
  *
  * Fetch error message into the buffer from the error handle provided
  */
-sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf)
+sb4 php_oci_fetch_errmsg(OCIError *error_handle, text *error_buf, size_t error_buf_size)
 {
        sb4 error_code = 0;
-       text err_buf[PHP_OCI_ERRBUF_LEN];
 
-       memset(err_buf, 0, sizeof(err_buf));
-       *error_buf = (text *)0;
-       PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, err_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR));
+       PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, error_buf, (ub4)error_buf_size, (ub4)OCI_HTYPE_ERROR));
 
        if (error_code) {
-               int err_buf_len = strlen((char *)err_buf);
+               int err_buf_len = strlen((char *)error_buf);
 
-               if (err_buf_len && err_buf[err_buf_len - 1] == '\n') {
-                       err_buf[err_buf_len - 1] = '\0';
-               }
-               if (err_buf_len && error_buf) {
-                       *error_buf = NULL;
-                       *error_buf = (text *)estrndup((char *)err_buf, err_buf_len);
+               if (err_buf_len && error_buf[err_buf_len - 1] == '\n') {
+                       error_buf[err_buf_len - 1] = '\0';
                }
        }
        return error_code;
@@ -2013,7 +1998,8 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
                                                        tmp = (php_oci_connection *)connection->id->ptr;
 
                                                        if (tmp != NULL && tmp->hash_key->len == hashed_details.s->len &&
-                                                               memcmp(tmp->hash_key->val, hashed_details.s->val, tmp->hash_key->len) == 0 && ++GC_REFCOUNT(connection->id) == SUCCESS) {
+                                                               memcmp(tmp->hash_key->val, hashed_details.s->val, tmp->hash_key->len) == 0) {
+                                                               ++GC_REFCOUNT(connection->id);
                                                                /* do nothing */
                                                        } else {
                                                                PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection);
@@ -2238,10 +2224,10 @@ static int php_oci_connection_ping(php_oci_connection *connection)
                return 1;
        } else {
                sb4 error_code = 0;
-               text tmp_buf[OCI_ERROR_MAXMSG_SIZE];
+               text tmp_buf[PHP_OCI_ERRBUF_LEN];
 
                /* Treat ORA-1010 as a successful Ping */
-               OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR);
+               OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
                if (error_code == 1010) {
                        return 1;
                }
@@ -2510,9 +2496,8 @@ int php_oci_password_change(php_oci_connection *connection, char *user, int user
  *
  * Get Oracle client library version
  */
-void php_oci_client_get_version(char **version)
+void php_oci_client_get_version(char *version, size_t version_size)
 {
-       char  version_buff[256];
 #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))      /* OCIClientVersion only available 10.2 onwards */
        sword major_version = 0;
        sword minor_version = 0;
@@ -2521,11 +2506,10 @@ void php_oci_client_get_version(char **version)
        sword port_update_num = 0;
 
        PHP_OCI_CALL(OCIClientVersion, (&major_version, &minor_version, &update_num, &patch_num, &port_update_num));
-       snprintf(version_buff, sizeof(version_buff), "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num);
+       snprintf(version, version_size, "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num);
 #else
-       memcpy(version_buff, "Unknown", sizeof("Unknown"));
+       memcpy(version, "Unknown", sizeof("Unknown"));
 #endif
-       *version = estrdup(version_buff);
 }
 /* }}} */
 
@@ -2533,12 +2517,11 @@ void php_oci_client_get_version(char **version)
  *
  * Get Oracle server version
  */
-int php_oci_server_get_version(php_oci_connection *connection, char **version)
+int php_oci_server_get_version(php_oci_connection *connection, char *version, size_t version_size)
 {
        sword errstatus;
-       char version_buff[256];
 
-       PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
+       PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version, version_size, OCI_HTYPE_SVCCTX));
 
        if (errstatus != OCI_SUCCESS) {
                connection->errcode = php_oci_error(connection->err, errstatus);
@@ -2546,7 +2529,6 @@ int php_oci_server_get_version(php_oci_connection *connection, char **version)
                return 1;
        }
 
-       *version = estrdup(version_buff);
        return 0;
 }
 /* }}} */
@@ -2560,7 +2542,7 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode)
        php_oci_descriptor *descriptor;
        ub4 lob_length;
        int column_size;
-       char *lob_buffer;
+       char *lob_buffer = (char *)0;
        int lob_fetch_status;
 
        if (column->indicator == -1) { /* column is NULL */
@@ -2606,6 +2588,8 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode)
                                } else {
                                        ZVAL_EMPTY_STRING(value);
                                }
+                               if (lob_buffer)
+                                       efree(lob_buffer);
                                return 0;
                        }
                } else {
@@ -2752,7 +2736,53 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg
     }
 #endif /* OCI_MAJOR_VERSION */
 
-       array_init(return_value);
+#if 0
+       if (expected_args > 2)
+       {
+               array_init(array);
+
+               for (i = 0; i < statement->ncolumns; i++) {
+
+                       column = php_oci_statement_get_column(statement, i + 1, NULL, 0);
+
+                       if (column == NULL) {
+                               continue;
+                       }
+                       if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) {
+                               continue;
+                       }
+
+                       if (!(column->indicator == -1)) {
+                               zval element;
+
+                               php_oci_column_to_zval(column, &element, fetch_mode);
+
+                               if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
+                                       add_index_zval(array, i, &element);
+                               }
+                               if (fetch_mode & PHP_OCI_ASSOC) {
+                                       if (fetch_mode & PHP_OCI_NUM) {
+                                               Z_TRY_ADDREF_P(&element);
+                                       }
+                                       add_assoc_zval(array, column->name, &element);
+                               }
+
+                       } else {
+                               if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
+                                       add_index_null(array, i);
+                               }
+                               if (fetch_mode & PHP_OCI_ASSOC) {
+                                       add_assoc_null(array, column->name);
+                               }
+                       }
+               }
+
+               /* RETURN_LONG(statement->ncolumns); */
+       }
+       else
+#endif
+       {
+               array_init(return_value);
 
        for (i = 0; i < statement->ncolumns; i++) {
 
@@ -2792,10 +2822,11 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg
 
        if (expected_args > 2) {
                /* Only for ocifetchinto BC.  In all other cases we return array, not long */
-               ZVAL_COPY_VALUE(array, return_value); /* copy return_value to given reference */
-               zval_dtor(return_value);
+               ZVAL_COPY(array, return_value); /* copy return_value to given reference */
+               /* zval_dtor(return_value); */
                RETURN_LONG(statement->ncolumns);
        }
+       }
 }
 /* }}} */
 
@@ -3061,7 +3092,7 @@ static OCIEnv *php_oci_create_env(ub2 charsetid)
 
        if (OCI_G(errcode) != OCI_SUCCESS) {
                sb4   ora_error_code = 0;
-               text  ora_msg_buf[OCI_ERROR_MAXMSG_SIZE];  /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
+               text  ora_msg_buf[PHP_OCI_ERRBUF_LEN];  /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
 
 #ifdef HAVE_OCI_INSTANT_CLIENT
                php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries");
@@ -3069,7 +3100,7 @@ static OCIEnv *php_oci_create_env(ub2 charsetid)
                php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
 #endif
                if (retenv
-                       && OCIErrorGet(retenv, (ub4)1, NULL, &ora_error_code, ora_msg_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
+                       && OCIErrorGet(retenv, (ub4)1, NULL, &ora_error_code, ora_msg_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
                        && *ora_msg_buf) {
                        php_error_docref(NULL, E_WARNING, "%s", ora_msg_buf);
                }
index 441dd448a537438cba01fe188ac2f0a533ca5f45..5f414bd4aef1c85c2d2683498b70b468acbb6c45 100644 (file)
@@ -88,11 +88,12 @@ PHP_FUNCTION(oci_define_by_name)
                RETURN_FALSE;
        }
 
-       define->name = (text*) estrndup(name, name_len);
+       define->name = (text*) ecalloc(1, name_len+1);
+       memcpy(define->name, name, name_len);
+       define->name[name_len] = '\0';
        define->name_len = name_len;
        define->type = type;
        define->zval = var;
-       Z_TRY_ADDREF_P(define->zval);
 
        RETURN_TRUE;
 }
@@ -183,7 +184,7 @@ PHP_FUNCTION(oci_free_descriptor)
 
        PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
 
-       zend_list_delete(descriptor->id);
+       zend_list_close(descriptor->id);
        RETURN_TRUE;
 }
 /* }}} */
@@ -305,7 +306,10 @@ PHP_FUNCTION(oci_lob_load)
                RETURN_FALSE;
        }
        if (buffer_len > 0) {
-               RETURN_STRINGL(buffer, buffer_len);
+        zend_string *ret = zend_string_init(buffer, buffer_len, 0);
+               if (buffer)
+                       efree(buffer);
+               RETURN_STR(ret);
        }
        else {
                RETURN_EMPTY_STRING();
@@ -350,7 +354,9 @@ PHP_FUNCTION(oci_lob_read)
                RETURN_FALSE;
        }       
        if (buffer_len > 0) {
-               RETURN_STRINGL(buffer, buffer_len);
+               zend_string *ret = zend_string_init(buffer, buffer_len, 0);
+               efree(buffer);
+               RETURN_STR(ret);
        }
        else {
                RETURN_EMPTY_STRING();
@@ -951,7 +957,11 @@ PHP_FUNCTION(oci_lob_export)
        if (length == -1) {
                length = lob_length - descriptor->lob_current_position;
        }
-       
+
+       if (lob_length == 0) {
+               length = 0;
+       }
+
        if (length == 0) {
                /* nothing to write, fail silently */
                RETURN_FALSE;
@@ -987,7 +997,8 @@ PHP_FUNCTION(oci_lob_export)
                }
                if (tmp_bytes_read && !php_stream_write(stream, buffer, tmp_bytes_read)) {
                        php_stream_close(stream);
-                       efree(buffer);
+                       if (buffer)
+                               efree(buffer);
                        RETURN_FALSE;
                }
                if (buffer) {
@@ -1545,7 +1556,7 @@ PHP_FUNCTION(oci_free_statement)
 
        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
 
-       zend_list_delete(statement->id);
+       zend_list_close(statement->id);
        RETURN_TRUE;
 }
 /* }}} */
@@ -1574,9 +1585,10 @@ PHP_FUNCTION(oci_close)
        }
 
        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
-       zend_list_delete(connection->id);
+       if (GC_REFCOUNT(connection->id) == 1)
+               zend_list_close(connection->id);
 
-       ZVAL_NULL(z_connection);
+       /* ZVAL_NULL(z_connection); */
        
        RETURN_TRUE;
 }
@@ -1613,7 +1625,7 @@ PHP_FUNCTION(oci_error)
        zval *arg = NULL;
        php_oci_statement *statement;
        php_oci_connection *connection;
-       text *errbuf;
+       text errbuf[PHP_OCI_ERRBUF_LEN];
        sb4 errcode = 0;
        dvoid *errh = NULL;
        ub2 error_offset = 0;
@@ -1663,15 +1675,13 @@ go_out:
                RETURN_FALSE;
        }
 
-       errcode = php_oci_fetch_errmsg(errh, &errbuf);
+       errcode = php_oci_fetch_errmsg(errh, errbuf, sizeof(errbuf));
 
        if (errcode) {
                array_init(return_value);
                add_assoc_long(return_value, "code", errcode);
                /* TODO: avoid reallocation ??? */
                add_assoc_string(return_value, "message", (char*) errbuf);
-               if (errbuf)
-                       efree(errbuf);
                add_assoc_long(return_value, "offset", error_offset);
                add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : "");
        } else {
@@ -2064,9 +2074,9 @@ PHP_FUNCTION(oci_result)
    Return a string containing runtime client library version information */
 PHP_FUNCTION(oci_client_version)
 {
-       char *version = NULL;
+       char version[256];
 
-       php_oci_client_get_version(&version);
+       php_oci_client_get_version(version, sizeof(version));
        RETURN_STRING(version);
 }
 /* }}} */
@@ -2077,7 +2087,8 @@ PHP_FUNCTION(oci_server_version)
 {
        zval *z_connection;
        php_oci_connection *connection;
-       char *version = NULL;
+       char version[256];
+       zend_string *ret;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_connection) == FAILURE) {
                return;
@@ -2085,11 +2096,12 @@ PHP_FUNCTION(oci_server_version)
 
        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
 
-       if (php_oci_server_get_version(connection, &version)) {
+       if (php_oci_server_get_version(connection, version, sizeof(version))) {
                RETURN_FALSE;
        }
        
-       RETURN_STRING(version);
+       ret = zend_string_init(version, strlen(version), 0);
+       RETURN_STR(ret);
 }
 /* }}} */
 
@@ -2189,7 +2201,7 @@ PHP_FUNCTION(oci_free_collection)
        
        PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
 
-       zend_list_delete(collection->id);
+       zend_list_close(collection->id);
        RETURN_TRUE;
 }
 /* }}} */
index d27a728d3c92dbf9d5a7c79f2fbcabcdb549530e..32ce365ea443f3f8b038d6ad6ce59d69e897028f 100644 (file)
@@ -91,7 +91,8 @@ php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char
        }
        
        if (query && query_len) {
-               statement->last_query = estrndup(query, query_len);
+               statement->last_query = ecalloc(1, query_len + 1);
+               memcpy(statement->last_query, query, query_len);
                statement->last_query_len = query_len;
        }
        else {
@@ -677,7 +678,8 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
                        }
                        PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
 
-                       outcol->name = estrndup((char*) colname, outcol->name_len);
+                       outcol->name = ecalloc(1, outcol->name_len + 1);
+                       memcpy(outcol->name, colname, outcol->name_len);
 
                        /* find a user-set define */
                        if (statement->defines) {
@@ -873,11 +875,6 @@ void php_oci_statement_free(php_oci_statement *statement)
                efree(statement->last_query);
        }
 
-       if (statement->columns) {
-               zend_hash_destroy(statement->columns);
-               efree(statement->columns);
-       }
-
        if (statement->binds) {
                zend_hash_destroy(statement->binds);
                efree(statement->binds);
@@ -888,6 +885,11 @@ void php_oci_statement_free(php_oci_statement *statement)
                efree(statement->defines);
        }
 
+       if (statement->columns) {
+               zend_hash_destroy(statement->columns);
+               efree(statement->columns);
+       }
+
        if (statement->parent_stmtid) {
                zend_list_delete(statement->parent_stmtid);
        }
@@ -1165,9 +1167,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
                                convert_to_string(var);
                        }
                        if (maxlength == -1) {
-                               value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0;
+                               /*
+                               value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : PHP_OCI_PIECE_SIZE;
+                               */
+                               /* We should use max length as dynamic bind is used */
+                               value_sz = PHP_OCI_PIECE_SIZE;
                        } else {
-                               value_sz = maxlength;
+                               if (maxlength == 0) {
+                                       value_sz = PHP_OCI_PIECE_SIZE;
+                               } else {
+                                       value_sz = maxlength;
+                               }
                        }
                        break;
 
@@ -1193,8 +1203,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
                                return 1;
                        }
                        convert_to_boolean(var);
-                       bind_data = (int *)&Z_LVAL_P(var);
-                       value_sz = sizeof(int);
+                       bind_data = (zend_long *)&Z_LVAL_P(var);
+                       if (Z_TYPE_P(var) == IS_TRUE)
+                               *(zend_long *)bind_data = 1;
+                       else if (Z_TYPE_P(var) == IS_FALSE)
+                               *(zend_long *)bind_data = 0;
+                       else {
+                               php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
+                               return 1;
+                       }
+
+                       value_sz = sizeof(zend_long);
 
                        mode = OCI_DEFAULT;
                        break;
@@ -1205,11 +1224,11 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
                        return 1;
                        break;
        }
-       
+
        if (value_sz == 0) {
                value_sz = 1;
        }
-       
+
        if (!statement->binds) {
                ALLOC_HASHTABLE(statement->binds);
                zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
@@ -1217,9 +1236,6 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
 
        if ((old_bind = zend_hash_str_find_ptr(statement->binds, name, name_len)) != NULL) {
                bindp = old_bind;
-               if (bindp->zval) {
-                       zval_ptr_dtor(bindp->zval);
-               }
        } else {
                zend_string *zvtmp;
                zvtmp = zend_string_init(name, name_len, 0);
@@ -1233,7 +1249,6 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
        bindp->parent_statement = statement;
        bindp->zval = var;
        bindp->type = type;
-       Z_TRY_ADDREF_P(bindp->zval);
        
        PHP_OCI_CALL_RETURN(errstatus,
                OCIBindByName,
@@ -1587,53 +1602,65 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam
                return 1;
        }
        
-       if (!statement->binds) {
-               ALLOC_HASHTABLE(statement->binds);
-               zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
-       }
-
-       zvtmp = zend_string_init(name, name_len, 0);
-       bindp = zend_hash_update_ptr(statement->binds, zvtmp, bind);
-       zend_string_release(zvtmp);
-
-       bindp->descriptor = NULL;
-       bindp->statement = NULL;
-       bindp->parent_statement = statement;
-       bindp->bind = NULL;
-       bindp->zval = var;
-       bindp->array.type = type;
-       bindp->indicator = 0;           /* not used for array binds */
-       bindp->type = 0;                        /* not used for array binds */
-
-       Z_TRY_ADDREF_P(var);
+       bind->descriptor = NULL;
+       bind->statement = NULL;
+       bind->parent_statement = statement;
+       bind->bind = NULL;
+       bind->zval = var;
+       bind->array.type = type;
+       bind->indicator = 0;            /* not used for array binds */
+       bind->type = 0;                         /* not used for array binds */
 
        PHP_OCI_CALL_RETURN(errstatus,
                                                        OCIBindByName,
                                                        (
                                                                statement->stmt,
-                                                               (OCIBind **)&bindp->bind,
+                                                               (OCIBind **)&bind->bind,
                                                                statement->err,
                                                                (text *)name,
                                                                name_len,
-                                                               (dvoid *) bindp->array.elements,
-                                                               (sb4) bindp->array.max_length,
+                                                               (dvoid *) bind->array.elements,
+                                                               (sb4) bind->array.max_length,
                                                                (ub2)type,
-                                                               (dvoid *)bindp->array.indicators,
-                                                               (ub2 *)bindp->array.element_lengths,
+                                                               (dvoid *)bind->array.indicators,
+                                                               (ub2 *)bind->array.element_lengths,
                                                                (ub2 *)0, /* bindp->array.retcodes, */
                                                                (ub4) max_table_length,
-                                                               (ub4 *) &(bindp->array.current_length),
+                                                               (ub4 *) &(bind->array.current_length),
                                                                (ub4) OCI_DEFAULT
                                                        )
                                                );
        
                
        if (errstatus != OCI_SUCCESS) {
-               efree(bindp);
+               if (bind->array.elements) {
+                       efree(bind->array.elements);
+               }
+
+               if (bind->array.element_lengths) {
+                       efree(bind->array.element_lengths);
+               }
+
+               if (bind->array.indicators) {
+                       efree(bind->array.indicators);
+               }
+
+               efree(bind);
+
                statement->errcode = php_oci_error(statement->err, errstatus);
                PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
                return 1;
        }
+
+       if (!statement->binds) {
+               ALLOC_HASHTABLE(statement->binds);
+               zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
+       }
+
+       zvtmp = zend_string_init(name, name_len, 0);
+       bindp = zend_hash_update_ptr(statement->binds, zvtmp, bind);
+       zend_string_release(zvtmp);
+
        statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
        return 0;
 }
index 4a23f06168df70e52d5768aaf593d21c6aa84cc0..d113775bdc7a048bde303ac3b2a315208f0e2711 100644 (file)
@@ -95,6 +95,13 @@ extern zend_class_entry *oci_coll_class_entry_ptr;
 #define PHP_OCI_LOB_BUFFER_ENABLED  1
 #define PHP_OCI_LOB_BUFFER_USED     2
 
+#ifdef OCI_ERROR_MAXMSG_SIZE2
+/* Bigger size is defined from 11.2.0.3 onwards */
+#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE2
+#else
+#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE
+#endif 
+
 /* The mode parameter for oci_connect() is overloaded and accepts both
  * privilege and external authentication flags OR'd together.
  * PHP_OCI_CRED_EXT must be distinct from the OCI_xxx privilege
@@ -144,7 +151,7 @@ typedef struct {
        sb4                             errcode;                                        /* last ORA- error number */
 
        HashTable          *descriptors;                                /* descriptors hash, used to flush all the LOBs using this connection on commit */
-       zend_ulong                      descriptor_count;                       /* used to index the descriptors hash table.  Not an accurate count */
+       zend_ulong              descriptor_count;                       /* used to index the descriptors hash table.  Not an accurate count */
        unsigned                is_open:1;                                      /* hels to determine if the connection is dead or not */
        unsigned                is_attached:1;                          /* hels to determine if we should detach from the server when closing/freeing the connection */
        unsigned                is_persistent:1;                        /* self-descriptive */
@@ -221,7 +228,7 @@ typedef struct {
        OCIStmt                         *stmt;                                  /* statement handle */
        char                            *last_query;                    /* last query issued. also used to determine if this is a statement or a refcursor received from Oracle */
        char                 impres_flag;           /* PHP_OCI_IMPRES_*_ */
-       zend_long                                last_query_len;                /* last query length */
+       zend_long                        last_query_len;                /* last query length */
        HashTable                       *columns;                               /* hash containing all the result columns */
        HashTable                       *binds;                                 /* binds hash */
        HashTable                       *defines;                               /* defines hash */
@@ -412,7 +419,7 @@ void php_oci_bind_hash_dtor(zval *data);
 void php_oci_descriptor_flush_hash_dtor(zval *data);
 void php_oci_connection_descriptors_free(php_oci_connection *connection);
 sb4 php_oci_error(OCIError *err_p, sword status);
-sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf);
+sb4 php_oci_fetch_errmsg(OCIError *error_handle, text *error_buf, size_t error_buf_size);
 int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset);
 void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive);
 php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, zend_long session_mode, int persistent, int exclusive);
@@ -420,8 +427,8 @@ int php_oci_connection_rollback(php_oci_connection *connection);
 int php_oci_connection_commit(php_oci_connection *connection);
 int php_oci_connection_release(php_oci_connection *connection);
 int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len);
-void php_oci_client_get_version(char **version);
-int php_oci_server_get_version(php_oci_connection *connection, char **version);
+void php_oci_client_get_version(char *version, size_t version_size);
+int php_oci_server_get_version(php_oci_connection *connection, char *version, size_t version_size);
 void php_oci_fetch_row(INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args);
 int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode);
 void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus);