Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix bug #54379 PDO_OCI: UTF-8 output gets truncated #59

Open
wants to merge 2 commits into from

5 participants

@kissifrot

I can test a Windows build ogf PHP with that fix if needed.

kissifrot added some commits
@kissifrot kissifrot Fix bug #54379 PDO_OCI: UTF-8 output gets truncated 35b1755
@kissifrot kissifrot Add test for bug #54379
It will probably need fixes/tweaks, especially with the given DSN at line 12
c119f13
@kissifrot

Added test.

@cjbj

I scanned the change quickly. The code looks delicate. It defines the new size in terms of a utext (a short) which is intended for utf-16. If this sizing code is the root cause of the crash, I would have expected the patch to use oratext or text with some character set multiplication factor.

The test uses the wrong number of args to putenv() so it will fail. It hardcodes the connection string and char set. It should also have a skipif if the DB char set is not UTF8.

@kissifrot

Which patch?

@lstrojny

Can you squash the commit?

@gureedo

It is not quite right solution.
Oracle docs defines three versions of utf8 encoding.

There is also another one caveat: NCHAR, NVARCHAR2, NCLOB types. Before transferring data to client Oracle converts data from such columns to NLS_NCHAR character set (if it is defined). Look here for details: http://docs.oracle.com/cd/A84870_01/doc/server.816/a76966/ch2.htm#94684
So, if NLS_NCHAR defined with different character set than connection charset or NLS_LANG, we can get invalid max character width for such columns.

I see here two ways.
1) Always multiply data_size by 4, and not support old UTF8 (Unicode 3.0) character set.
2) Detect character set and multiply by obtained max width.

But i don't know what to do with NLS_NCHAR.

@gitgitcode

use oci function cast() like this :
select cast( tbl.description AS
varchar2(300) )as desc FROM database.table tbl;

it work :8ball:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 18, 2012
  1. @kissifrot
Commits on May 5, 2012
  1. @kissifrot

    Add test for bug #54379

    kissifrot authored
    It will probably need fixes/tweaks, especially with the given DSN at line 12
This page is out of date. Refresh to see the latest.
Showing with 49 additions and 1 deletion.
  1. +1 −1  ext/pdo_oci/oci_statement.c
  2. +48 −0 ext/pdo_oci/tests/bug54379.phpt
View
2  ext/pdo_oci/oci_statement.c
@@ -529,7 +529,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
(param, OCI_DTYPE_PARAM, &colname, &namelen, OCI_ATTR_NAME, S->err));
col->precision = scale;
- col->maxlen = data_size;
+ col->maxlen = ( data_size + 1 ) * sizeof(utext);
col->namelen = namelen;
col->name = estrndup((char *)colname, namelen);
View
48 ext/pdo_oci/tests/bug54379.phpt
@@ -0,0 +1,48 @@
+--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';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+putenv('PDO_OCI_TEST_DSN', 'oci:dbname=localhost/xe;charset=AL32UTF8');
+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_utf8_trunc");
+} catch (Exception $e) {
+}
+
+
+$db->exec("CREATE TABLE test_utf8_trunc (col1 NVARCHAR2(20))");
+$db->exec("INSERT INTO test_utf8_trunc VALUES('12345678901234567890')");
+$db->exec("INSERT INTO test_utf8_trunc VALUES('あいうえおかきくけこさしすせそたちつてと')");
+
+$stmt = $db->prepare("SELECT * FROM test_utf8_trunc");
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+$db->exec("DROP TABLE test_utf8_trunc");
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ array(1) {
+ ["COL1"]=>
+ string(20) "12345678901234567890"
+ }
+ [1]=>
+ array(1) {
+ ["COL1"]=>
+ string(40) "あいうえおかきくけこさしすせそたちつてと"
+ }
+}
Something went wrong with that request. Please try again.