Skip to content

Commit e80ea04

Browse files
committed
Fixed bug #54379 (PDO_OCI: UTF-8 output gets truncated)
This was a modification of an incomplete PR #2276.
1 parent dfcb11d commit e80ea04

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ PHP NEWS
6060
. Fixed bug #74159 (Writing a large buffer to a non-blocking encrypted stream
6161
fails with "bad write retry"). (trowski)
6262

63+
- PDO_OCI:
64+
. Fixed bug #54379 (PDO_OCI: UTF-8 output gets truncated). (gureedo / Oracle)
65+
6366
- Standard:
6467
. Fixed bug #74148 (ReflectionFunction incorrectly reports the number of
6568
arguments). (Laruence)

ext/pdo_oci/oci_driver.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,13 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
699699
goto cleanup;
700700
}
701701

702+
/* Get max character width */
703+
H->last_err = OCINlsNumericInfoGet(H->env, H->err, &H->max_char_width, OCI_NLS_CHARSET_MAXBYTESZ);
704+
if (H->last_err) {
705+
oci_drv_error("OCINlsNumericInfoGet: OCI_NLS_CHARSET_MAXBYTESZ");
706+
goto cleanup;
707+
}
708+
702709
dbh->methods = &oci_methods;
703710
dbh->alloc_own_columns = 1;
704711
dbh->native_case = PDO_CASE_UPPER;

ext/pdo_oci/oci_statement.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,12 +599,12 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
599599
} else if (dtype == SQLT_IBFLOAT || dtype == SQLT_IBDOUBLE) {
600600
S->cols[colno].datalen = 1024;
601601
#endif
602+
} else if (dtype == SQLT_BIN) {
603+
S->cols[colno].datalen = (ub4) col->maxlen * 2; // raw characters to hex digits
602604
} else {
603-
S->cols[colno].datalen = (ub4) col->maxlen;
604-
}
605-
if (dtype == SQLT_BIN) {
606-
S->cols[colno].datalen *= 3;
605+
S->cols[colno].datalen = (ub4) (col->maxlen * S->H->max_char_width);
607606
}
607+
608608
S->cols[colno].data = emalloc(S->cols[colno].datalen + 1);
609609
dtype = SQLT_CHR;
610610

ext/pdo_oci/php_pdo_oci_int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ typedef struct {
3838
ub4 prefetch;
3939
ub2 charset;
4040
sword last_err;
41+
sb4 max_char_width;
4142

4243
unsigned attached:1;
4344
unsigned _reserved:31;

ext/pdo_oci/tests/bug54379.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Bug #54379 (PDO_OCI: UTF-8 output gets truncated)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_oci'))
6+
die('skip not loaded');
7+
require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc';
8+
if (!preg_match('/charset=.*utf8/i', getenv('PDOTEST_DSN')))
9+
die('skip not UTF8 DSN');
10+
PDOTest::skip();
11+
?>
12+
--FILE--
13+
<?php
14+
require 'ext/pdo/tests/pdo_test.inc';
15+
$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt');
16+
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
17+
try {
18+
$db->exec("DROP TABLE test");
19+
} catch (Exception $e) {
20+
}
21+
$db->exec("CREATE TABLE test (col1 NVARCHAR2(20))");
22+
$db->exec("INSERT INTO test VALUES('12345678901234567890')");
23+
$db->exec("INSERT INTO test VALUES('あいうえおかきくけこさしすせそたちつてと')");
24+
$stmt = $db->prepare("SELECT * FROM test");
25+
$stmt->execute();
26+
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
27+
$db->exec("DROP TABLE test");
28+
?>
29+
--EXPECTF--
30+
array(2) {
31+
[0]=>
32+
array(1) {
33+
["col1"]=>
34+
string(20) "12345678901234567890"
35+
}
36+
[1]=>
37+
array(1) {
38+
["col1"]=>
39+
string(60) "あいうえおかきくけこさしすせそたちつてと"
40+
}
41+
}

0 commit comments

Comments
 (0)