diff options
author | Christopher Jones <christopher.jones@oracle.com> | 2017-03-02 15:28:01 +1100 |
---|---|---|
committer | Christopher Jones <christopher.jones@oracle.com> | 2017-03-02 15:28:01 +1100 |
commit | e80ea04c79fb1bb38cdd836e0622f7598727e888 (patch) | |
tree | 3fcb0c0fdb3c0ebdefa62e1456a9733cc92efeaf /ext/pdo_oci | |
parent | dfcb11d7d1c4ec7cc7ef77d8e42190f91cb75f97 (diff) | |
download | php-git-e80ea04c79fb1bb38cdd836e0622f7598727e888.tar.gz |
Fixed bug #54379 (PDO_OCI: UTF-8 output gets truncated)
This was a modification of an incomplete PR #2276.
Diffstat (limited to 'ext/pdo_oci')
-rw-r--r-- | ext/pdo_oci/oci_driver.c | 7 | ||||
-rw-r--r-- | ext/pdo_oci/oci_statement.c | 8 | ||||
-rw-r--r-- | ext/pdo_oci/php_pdo_oci_int.h | 1 | ||||
-rw-r--r-- | ext/pdo_oci/tests/bug54379.phpt | 41 |
4 files changed, 53 insertions, 4 deletions
diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 367f478e12..a86b6d9613 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -699,6 +699,13 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ * 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 5d34957885..306713bac3 100644 --- a/ext/pdo_oci/oci_statement.c +++ b/ext/pdo_oci/oci_statement.c @@ -599,12 +599,12 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ } else if (dtype == SQLT_IBFLOAT || dtype == SQLT_IBDOUBLE) { S->cols[colno].datalen = 1024; #endif + } else if (dtype == SQLT_BIN) { + S->cols[colno].datalen = (ub4) col->maxlen * 2; // raw characters to hex digits } else { - S->cols[colno].datalen = (ub4) col->maxlen; - } - if (dtype == SQLT_BIN) { - S->cols[colno].datalen *= 3; + S->cols[colno].datalen = (ub4) (col->maxlen * S->H->max_char_width); } + S->cols[colno].data = emalloc(S->cols[colno].datalen + 1); dtype = SQLT_CHR; diff --git a/ext/pdo_oci/php_pdo_oci_int.h b/ext/pdo_oci/php_pdo_oci_int.h index ab437c14a8..5d066e53b8 100644 --- a/ext/pdo_oci/php_pdo_oci_int.h +++ b/ext/pdo_oci/php_pdo_oci_int.h @@ -38,6 +38,7 @@ typedef struct { ub4 prefetch; 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 0000000000..abb6bc73e1 --- /dev/null +++ b/ext/pdo_oci/tests/bug54379.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #54379 (PDO_OCI: UTF-8 output gets truncated) +--SKIPIF-- +<?php +if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) +die('skip not loaded'); +require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc'; +if (!preg_match('/charset=.*utf8/i', getenv('PDOTEST_DSN'))) +die('skip not UTF8 DSN'); +PDOTest::skip(); +?> +--FILE-- +<?php +require 'ext/pdo/tests/pdo_test.inc'; +$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt'); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +try { + $db->exec("DROP TABLE test"); +} catch (Exception $e) { +} +$db->exec("CREATE TABLE test (col1 NVARCHAR2(20))"); +$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(60) "あいうえおかきくけこさしすせそたちつてと" + } +} |