summaryrefslogtreecommitdiffstats
path: root/bug69975.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bug69975.patch')
-rw-r--r--bug69975.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/bug69975.patch b/bug69975.patch
new file mode 100644
index 0000000..4aafb17
--- /dev/null
+++ b/bug69975.patch
@@ -0,0 +1,89 @@
+Adapted for 5.4, by Remi Collet, from:
+
+
+From 82637e818776d4fe778fb1dbac26eeece02e900c Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmb@php.net>
+Date: Fri, 3 Jul 2015 00:04:50 +0200
+Subject: [PATCH] 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)
+---
+ ext/odbc/php_odbc.c | 7 +++++++
+ ext/odbc/tests/bug69975.phpt | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 39 insertions(+)
+ create mode 100644 ext/odbc/tests/bug69975.phpt
+
+diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
+index ddfbc4e..1d70b7f 100644
+--- a/ext/odbc/php_odbc.c
++++ b/ext/odbc/php_odbc.c
+@@ -1005,6 +1005,14 @@ int odbc_bindcols(odbc_result *result TS
+ default:
+ rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), colfieldid,
+ NULL, 0, NULL, &displaysize);
++#if defined(ODBCVER) && (ODBCVER >= 0x0300)
++ /* 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) {
+ 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');
++?>
+--
+2.1.4
+