Bug #80460 [NoF]: ODBC doesn't account for SQL_NO_TOTAL indicator, causing segmentation fault

From: Date: Mon, 08 Feb 2021 13:30:14 +0000
Subject: Bug #80460 [NoF]: ODBC doesn't account for SQL_NO_TOTAL indicator, causing segmentation fault
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232009@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80460&edit=1

 ID:                 80460
 Updated by:         cmb@php.net
 Reported by:        mirish at ibm dot com
 Summary:            ODBC doesn't account for SQL_NO_TOTAL indicator,
                     causing segmentation fault
 Status:             No Feedback
 Type:               Bug
 Package:            ODBC related
 Operating System:   RHEL 7.9
 PHP Version:        Irrelevant
 Assigned To:        cmb
 Block user comment: N
 Private report:     N

 New Comment:

> according to IBM support we have a related problem […]

This ticket is about a segmentation fault in the ODBC extension;
your issue is about truncation of strings in the PDO_ODBC
extension.  Please report that as separate ticket.


Previous Comments:
------------------------------------------------------------------------
[2021-02-08 13:12:34] ml at menten dot com

Hello,

according to IBM support we have a related problem reading special characters from VARGRAPHIC fields
in PHP 7.3.26 with the following driver: 

IBM i Access Client Solutions - PASE Application Package for IBM i.
Connectivity to Db2® for i using ODBC with unixODBC
ibm-iaccess.ppc64 1.1.0.14-0 @/ibm-iaccess-1.1.0.14-0.ibmi7.2.ppc64

If we write to a VARGRAPHIC field of length 70, for example, we can write the full 70 characters,
but we can only read them if the 70 characters do not consist of special characters or if there are
at most 35 special characters (e.g. ä).
For example, if we have i special characters and 69 non-special characters in the field, it cannot
be read out either. Analogously, this problem also occurs with CHAR and VARCHAR fields. 

Test Script:


<?php
ini_set('display_errors', true);
header('Content-Type: text/html; charset=utf-8');
ini_set("default_mimetype", "text/html");
ini_set("default_charset", "UTF-8");




// setup
$user = "test";
$pw = "test";


// full 70 length / no special characters -> OK
#	$test = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

// 35 length / all special characters -> OK
#	$test =
"äääääääääääääääääääääääääääääääääää";

// 36 length / 35 special characters, 1 normal character -> no result
$test =
"äääääääääääääääääääääääääääääääääää1";

// 52 length / 35 normal characters, 17 special character -> OK
#	$test =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaäääääääääääääääää";

// 53 length / 35 normal characters, 18 special character -> no result
#	$test =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaääääääääääääääääää";

// full 70 length / 70 special characters -> no result
#	$test =
"ääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääää";



try
{
	$connection = new PDO("odbc:DRIVER={IBM i Access ODBC
Driver};SYSTEM=localhost;DATABASE=*LOCAL;NAM=1;DBQ=IEFFECTDB,IEFFECT28;CCSID=1208;DEBUG=524288",
$user, $pw, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
}
catch (Exception $e)
{
	echo($e->getMessage());
	echo "<br>";
	echo($e->getCode());
	
	die();
}


// create table
$query = "CREATE TABLE IEFFECTDB/TEST (TEST1 VARGRAPHIC(70) ccsid 1200 NOT null DEFAULT
'')";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);


// insert
$query = "INSERT INTO IEFFECTDB/TEST (TEST1) VALUES (?)";
$params = array($test);
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);


// select
$query = "SELECT TEST1 FROM IEFFECTDB/TEST";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);
echo "<pre>";
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
echo "<pre>";


// drop table
$query = "DROP TABLE IEFFECTDB/TEST";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);


$connection = null;

echo
"------------------------------------------------------------------------------------------------------------";
echo "<br><br>";


try
{
	$connection = new PDO("odbc:DRIVER={IBM i Access ODBC
Driver};SYSTEM=localhost;DATABASE=*LOCAL;NAM=1;DBQ=IEFFECTDB,IEFFECT28;CCSID=1208", $user, $pw,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
}
catch (Exception $e)
{
	echo($e->getMessage());
	echo "<br>";
	echo($e->getCode());
	
	die();
}


// create table
$query = "CREATE TABLE IEFFECTDB/TEST (TEST1 VARGRAPHIC(70) ccsid 1200 NOT null DEFAULT
'')";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);


// insert
$query = "INSERT INTO IEFFECTDB/TEST (TEST1) VALUES (?)";
$params = array($test);
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);


// select
$query = "SELECT TEST1 FROM IEFFECTDB/TEST";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);
echo "<pre>";
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
echo "<pre>";


// drop table
$query = "DROP TABLE IEFFECTDB/TEST";
$params = array();
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);

------------------------------------------------------------------------
[2020-12-13 04:22:09] php-bugs at lists dot php dot net

No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.

------------------------------------------------------------------------
[2020-12-04 15:57:28] cmb@php.net

While the other bug report was indeed about SQL_NO_DATA, the fix
is supposed to cater to any result other than SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO, and to return early in those cases.

Anyway, could you please generate a stack backtrace[1] and post it
here (or provide it somewhere else if it is very large)?

[1] <https://bugs.php.net/bugs-generating-backtrace.php>

------------------------------------------------------------------------
[2020-12-02 17:07:42] mirish at ibm dot com

It doesn't look like they are related. Bug #44618 seems to note that it should handle
SQL_NO_DATA, but that is a cursor indicator different from SQL_NO_TOTAL, which indicates that there
is data left to retrieve, but the driver doesn't know (or doesn't want to calculate) how
much data is left. As written, SQL_NO_TOTAL indicator (-4) is passed as a length to string
functions.

I can confirm that this segmentation fault occurs on 7.4.13.

------------------------------------------------------------------------
[2020-12-02 10:55:01] cmb@php.net

Isn't the second part basically a duplicate of bug #44618, which
is supposed to be fixed as of PHP 7.3.25 and 7.4.13?

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=80460


--
Edit this bug report at https://bugs.php.net/bug.php?id=80460&edit=1


Thread (19 messages)

« previous php.bugs (#232009) next »