summaryrefslogtreecommitdiff
path: root/ext/oci8/oci8_lob.c
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2007-03-29 09:33:04 +0000
committerAntony Dovgal <tony2001@php.net>2007-03-29 09:33:04 +0000
commit26cf62d293673f5714f812ef4eb17f5a588bdbca (patch)
tree3745ee933b06a55e554f58dca17c6d9e48847652 /ext/oci8/oci8_lob.c
parent4a119f9a79b5db25ba41da8da8e4292c46aafa1f (diff)
downloadphp-git-26cf62d293673f5714f812ef4eb17f5a588bdbca.tar.gz
MFH: fix PECL bug #10194 (crash in Oracle client when memory limit reached in the callback)
preallocate the required buffer, so that it would fail earlier.
Diffstat (limited to 'ext/oci8/oci8_lob.c')
-rw-r--r--ext/oci8/oci8_lob.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c
index 624a755dcf..10dcdcddbe 100644
--- a/ext/oci8/oci8_lob.c
+++ b/ext/oci8/oci8_lob.c
@@ -160,7 +160,12 @@ sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece)
switch (piece)
{
case OCI_LAST_PIECE:
- *(ctx->lob_data) = erealloc(*(ctx->lob_data), (size_t) (*(ctx->lob_len) + lenp + 1));
+ if ((*(ctx->lob_len) + lenp) > (ctx->alloc_len)) {
+ /* this should not happen ever */
+ *(ctx->lob_data) = NULL;
+ *(ctx->lob_len) = 0;
+ return OCI_ERROR;
+ }
memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
*(ctx->lob_len) += lenp;
*(*(ctx->lob_data) + *(ctx->lob_len)) = 0x00;
@@ -168,7 +173,12 @@ sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece)
case OCI_FIRST_PIECE:
case OCI_NEXT_PIECE:
- *(ctx->lob_data) = erealloc(*(ctx->lob_data), (size_t) (*(ctx->lob_len) + lenp));
+ if ((*(ctx->lob_len) + lenp) > ctx->alloc_len) {
+ /* this should not happen ever */
+ *(ctx->lob_data) = NULL;
+ *(ctx->lob_len) = 0;
+ return OCI_ERROR;
+ }
memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
*(ctx->lob_len) += lenp;
return OCI_CONTINUE;
@@ -176,7 +186,6 @@ sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece)
default: {
TSRMLS_FETCH();
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected LOB piece id received (value:%d)", piece);
- efree(*(ctx->lob_data));
*(ctx->lob_data) = NULL;
*(ctx->lob_len) = 0;
return OCI_ERROR;
@@ -226,16 +235,19 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
oraub8 bytes_read, offset = 0;
oraub8 requested_len = read_length; /* this is by default */
oraub8 chars_read = 0;
- int is_clob = 0;
#else
int bytes_read, offset = 0;
int requested_len = read_length; /* this is by default */
#endif
+ int is_clob = 0;
+ sb4 bytes_per_char = 1;
*data_len = 0;
*data = NULL;
+
ctx.lob_len = data_len;
ctx.lob_data = data;
+ ctx.alloc_len = 0;
if (php_oci_lob_get_length(descriptor, &length TSRMLS_CC)) {
return 1;
@@ -272,9 +284,7 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
return 1;
}
- }
-#ifdef HAVE_OCI_LOB_READ2
- else {
+ } else {
ub2 charset_id = 0;
PHP_OCI_CALL_RETURN(connection->errcode, OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id));
@@ -291,6 +301,22 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
}
if (is_clob) {
+ PHP_OCI_CALL_RETURN(connection->errcode, OCINlsNumericInfoGet, (connection->env, connection->err, &bytes_per_char, OCI_NLS_CHARSET_MAXBYTESZ));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ } else {
+ /* BLOBs don't have encoding, so bytes_per_char == 1 */
+ }
+
+ ctx.alloc_len = (requested_len + 1) * bytes_per_char;
+ *data = ecalloc(bytes_per_char, requested_len + 1);
+
+#ifdef HAVE_OCI_LOB_READ2
+ if (is_clob) {
chars_read = requested_len;
bytes_read = 0;
} else {