com php-src: Fixed bug #54379 (PDO_OCI: UTF-8 outpu t gets truncated): NEWS ext/pdo_oci/oci_driver .c ext/pdo_oci/oci_statement.c ext/pdo_oci/php_ pdo_oci_int.h ext/pdo_oci/tests/bug54379. phpt

[email protected] (Christopher Jones)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    e80ea04c79fb1bb38cdd836e0622f7598727e888
Author:    Christopher Jones <[email protected]>         Thu, 2 Mar 2017 15:28:01 +1100
Parents:   dfcb11d7d1c4ec7cc7ef77d8e42190f91cb75f97
Branches:  PHP-7.0

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=e80ea04c79fb1bb38cdd836e0622f7598727e888

Log:
Fixed bug #54379 (PDO_OCI: UTF-8 output gets truncated)

This was a modification of an incomplete PR #2276.

Bugs:
https://bugs.php.net/54379
https://bugs.php.net/2276

Changed paths:
  M  NEWS
  M  ext/pdo_oci/oci_driver.c
  M  ext/pdo_oci/oci_statement.c
  M  ext/pdo_oci/php_pdo_oci_int.h
  A  ext/pdo_oci/tests/bug54379.phpt


Diff:
diff --git a/NEWS b/NEWS
index d156529..4d605ef 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,9 @@ PHP                                                                        NEWS
   . Fixed bug #74159 (Writing a large buffer to a non-blocking encrypted stream
     fails with "bad write retry"). (trowski)
 
+- PDO_OCI:
+  . Fixed bug #54379 (PDO_OCI: UTF-8 output gets truncated). (gureedo / Oracle)
+
 - Standard:
   . Fixed bug #74148 (ReflectionFunction incorrectly reports the number of
     arguments). (Laruence)
diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c
index 367f478..a86b6d9 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 5d34957..306713b 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 ab437c1..5d066e5 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 0000000..abb6bc7
--- /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) "あいうえおかきくけこさしすせそたちつてと"
+  }
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.