summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmb@php.net>2015-07-03 00:04:50 +0200
committerJulien Pauli <jpauli@php.net>2016-07-08 15:33:46 +0200
commit82637e818776d4fe778fb1dbac26eeece02e900c (patch)
tree2f43f7ed9788654b272f3512e8771bfb927c8939
parent51b584b1596e390ea989b400ef2de392b560ee79 (diff)
downloadphp-git-82637e818776d4fe778fb1dbac26eeece02e900c.tar.gz
Fix #69975: PHP segfaults when accessing nvarchar(max) defined columns
The SQL Server Native Client 11.0 and maybe other ODBC drivers report NVARCHAR(MAX) columns as SQL_WVARCHAR with size 0. This causes too small a buffer to be emalloc'd, likely causing a segfault in the following. As we don't know the real size of the column data, we treat such colums as SQL_WLONGVARCHAR. The related bug #67437 suggests that some drivers report a size of ~4GB. It is not certain that this is really the case (there might be some integer overflow involved, and anyway, there has been no feedback), so we do not cater for this now. However, it would not be hard to treat all sizes above a certain threshold in a similar way, i.e. as SQL_WLONGVARCHAR. (cherry picked from commit 16db4d1462bf3eacb93c0cd940f799160a284b24) (cherry picked from commit 344ff5dd4c538eaebea075f7705321f8b86d0b47)
-rw-r--r--ext/odbc/php_odbc.c7
-rw-r--r--ext/odbc/tests/bug69975.phpt32
2 files changed, 39 insertions, 0 deletions
diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index ddfbc4edbe..1d70b7fd19 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -1007,6 +1007,13 @@ int odbc_bindcols(odbc_result *result TSRMLS_DC)
rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_DISPLAY_SIZE,
NULL, 0, NULL, &displaysize);
}
+
+ /* Workaround for drivers that report NVARCHAR(MAX) columns as SQL_WVARCHAR with size 0 (bug #69975) */
+ if (result->values[i].coltype == SQL_WVARCHAR && displaysize == 0) {
+ result->values[i].coltype = SQL_WLONGVARCHAR;
+ result->values[i].value = NULL;
+ break;
+ }
#endif
/* Workaround for Oracle ODBC Driver bug (#50162) when fetching TIMESTAMP column */
if (result->values[i].coltype == SQL_TIMESTAMP) {
diff --git a/ext/odbc/tests/bug69975.phpt b/ext/odbc/tests/bug69975.phpt
new file mode 100644
index 0000000000..eca7564519
--- /dev/null
+++ b/ext/odbc/tests/bug69975.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #69975 (PHP segfaults when accessing nvarchar(max) defined columns)
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+include 'config.inc';
+
+$conn = odbc_connect($dsn, $user, $pass);
+@odbc_exec($conn, 'CREATE DATABASE odbcTEST');
+odbc_exec($conn, 'CREATE TABLE FOO (ID INT, VARCHAR_COL NVARCHAR(MAX))');
+odbc_exec($conn, "INSERT INTO FOO VALUES (1, 'foo')");
+
+$result = odbc_exec($conn, "SELECT VARCHAR_COL FROM FOO");
+var_dump(odbc_fetch_array($result));
+
+echo "ready";
+?>
+--EXPECT--
+array(1) {
+ ["VARCHAR_COL"]=>
+ string(3) "foo"
+}
+ready
+--CLEAN--
+<?php
+include 'config.inc';
+
+$conn = odbc_connect($dsn, $user, $pass);
+odbc_exec($conn, 'DROP TABLE FOO');
+odbc_exec($conn, 'DROP DATABASE odbcTEST');
+?>