diff options
author | Antony Dovgal <tony2001@php.net> | 2007-03-29 09:33:04 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2007-03-29 09:33:04 +0000 |
commit | 26cf62d293673f5714f812ef4eb17f5a588bdbca (patch) | |
tree | 3745ee933b06a55e554f58dca17c6d9e48847652 /ext/oci8/oci8_lob.c | |
parent | 4a119f9a79b5db25ba41da8da8e4292c46aafa1f (diff) | |
download | php-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.c | 40 |
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 { |