90 lines
3.0 KiB
Diff
90 lines
3.0 KiB
Diff
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
|
|
|