com php-src: Fix #69975: PHP segfaults when accessing nvarchar(max) defined columns: ext/odbc/php_odbc.c ext/odbc/tests/bug699 75.phpt

From: Date: Thu, 02 Jul 2015 22:15:47 +0000
Subject: com php-src: Fix #69975: PHP segfaults when accessing nvarchar(max) defined columns: ext/odbc/php_odbc.c ext/odbc/tests/bug699 75.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-87715@lists.php.net to get a copy of this message
Commit: 16db4d1462bf3eacb93c0cd940f799160a284b24 Author: Christoph M. Becker <cmb@php.net> Fri, 3 Jul 2015 00:04:50 +0200 Parents: 57525d01dc29804903f03e471cf117e077d86ca4 Branches: PHP-5.6 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=16db4d1462bf3eacb93c0cd940f799160a284b24 Log: 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. Bugs: https://bugs.php.net/69975 https://bugs.php.net/67437 Changed paths: M ext/odbc/php_odbc.c A ext/odbc/tests/bug69975.phpt Diff: diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index ddfbc4e...80af492 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1008,6 +1008,13 @@ int odbc_bindcols(odbc_result *result TSRMLS_DC) NULL, 0, NULL, &displaysize); } #endif + /* 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; + } + /* Workaround for Oracle ODBC Driver bug (#50162) when fetching TIMESTAMP column */ if (result->values[i].coltype == SQL_TIMESTAMP) { displaysize += 3; diff --git a/ext/odbc/tests/bug69975.phpt b/ext/odbc/tests/bug69975.phpt new file mode 100644 index 0000000..eca7564 --- /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'); +?>

« previous php.cvs (#87715) next »