summaryrefslogtreecommitdiff
path: root/ext/pdo_oci
diff options
context:
space:
mode:
authorChristopher Jones <christopher.jones@oracle.com>2017-03-02 15:28:01 +1100
committerChristopher Jones <christopher.jones@oracle.com>2017-03-02 15:28:01 +1100
commite80ea04c79fb1bb38cdd836e0622f7598727e888 (patch)
tree3fcb0c0fdb3c0ebdefa62e1456a9733cc92efeaf /ext/pdo_oci
parentdfcb11d7d1c4ec7cc7ef77d8e42190f91cb75f97 (diff)
downloadphp-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.c7
-rw-r--r--ext/pdo_oci/oci_statement.c8
-rw-r--r--ext/pdo_oci/php_pdo_oci_int.h1
-rw-r--r--ext/pdo_oci/tests/bug54379.phpt41
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) "あいうえおかきくけこさしすせそたちつてと"
+ }
+}