From ec03eaef2e9a1aa72bfa85dcf328a2ddada90af1 Mon Sep 17 00:00:00 2001 From: gureedo Date: Wed, 11 Dec 2013 14:24:43 +0600 Subject: [PATCH] Fix bug #54379 PDO_OCI: UTF-8 output gets truncated --- ext/pdo_oci/oci_driver.c | 7 +++++ ext/pdo_oci/oci_statement.c | 7 ++--- ext/pdo_oci/php_pdo_oci_int.h | 1 + ext/pdo_oci/tests/bug54379.phpt | 47 +++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 ext/pdo_oci/tests/bug54379.phpt diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 8f56c674d102e..2e4f9aebaad21 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -694,6 +694,13 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC goto cleanup; } + /* Get max character width */ + H->last_err = OCINlsNumericInfoGet(H->env, H->err, &H->max_char_width, OCI_NLS_CHARSET_MAXBYTESZ); + if (H->last_err) { + oci_drv_error("OCINlsNumericInfoGet: OCI_NLS_CHARSET_MAXBYTESZ"); + goto cleanup; + } + dbh->methods = &oci_methods; dbh->alloc_own_columns = 1; dbh->native_case = PDO_CASE_UPPER; diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c index 4e341c08bebff..7963a81930c9c 100644 --- a/ext/pdo_oci/oci_statement.c +++ b/ext/pdo_oci/oci_statement.c @@ -582,11 +582,12 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */ } else { S->cols[colno].datalen = col->maxlen; } - if (dtype == SQLT_BIN) { - S->cols[colno].datalen *= 3; + dtype = SQLT_CHR; + if (dtype == SQLT_CHR) { + S->cols[colno].datalen *= S->H->max_char_width; } S->cols[colno].data = emalloc(S->cols[colno].datalen + 1); - dtype = SQLT_CHR; + /* returning data as a string */ col->param_type = PDO_PARAM_STR; diff --git a/ext/pdo_oci/php_pdo_oci_int.h b/ext/pdo_oci/php_pdo_oci_int.h index 4979aadb1385b..04509064e2f0a 100644 --- a/ext/pdo_oci/php_pdo_oci_int.h +++ b/ext/pdo_oci/php_pdo_oci_int.h @@ -37,6 +37,7 @@ typedef struct { /* OCI9; 0 == use NLS_LANG */ ub2 charset; sword last_err; + sb4 max_char_width; unsigned attached:1; unsigned _reserved:31; diff --git a/ext/pdo_oci/tests/bug54379.phpt b/ext/pdo_oci/tests/bug54379.phpt new file mode 100644 index 0000000000000..36d86632ebeed --- /dev/null +++ b/ext/pdo_oci/tests/bug54379.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #54379 (PDO_OCI: UTF-8 output gets truncated) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +try { + $db->exec("DROP TABLE test"); +} catch (Exception $e) { +} + +$db->exec("CREATE TABLE test (col1 NVARCHAR2(100))"); +$db->exec("INSERT INTO test VALUES('12345678901234567890')"); +$db->exec("INSERT INTO test VALUES('Русские символы по три байта')"); + +$stmt = $db->prepare("SELECT * FROM test"); + +$stmt->execute(); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); + +$db->exec("DROP TABLE test"); + +?> +--EXPECTF-- +array(2) { + [0]=> + array(1) { + ["col1"]=> + string(20) "12345678901234567890" + } + [1]=> + array(1) { + ["col1"]=> + string(52) "Русские символы по три байта" + } +} \ No newline at end of file