Skip to content

PDO_ODBC can inject garbage into field values #16450

Closed
@studata

Description

@studata

Description

Running the following code works fine, as long as the content of the “MyLongText” database field is not longer than 2048 characters. The command var_dump($row); returns “string(2048)” and the expected field content.

When adding one additional character to the database field (in this example 2049 underscores), var_dump($row); returns “string(4098)” -- exactly twice the effective text length in the database field -- and shows that inside the text from the database field, some unreadable string is injected like:
�=@$�����_@Pj_?_�����`j?_�۶�������___m_E_�9l���P_Pm_B_0���������_����m_d

For field contents of more than 2048 characters, the length of the content returned by PDO is always doubled; 2050 characters in the database field are returned by var_dump as “string(4100)”.

Using “odbc_connect” instead of “new PDO” the command “var_dump($row1["MyLongText"]);” returns “string(2049)” – as expected - and shows the correct content from the database field “MyLongText”.

The installed ODBC driver on the server is provided by "Microsoft Access Database Engine 2016 Redistributable"

The issue with PDO_ODBC occurs with PHP 8.0, 8.1, 8.2, 8.3 and 8.4. When downgrading to PHP 7.4 this php code works as expected.
The behaviour is similar to that described under https://bugs.php.net/bug.php?id=81688 .

<?php

header("content-type: text/html; charset=utf-8");

$dbFile = "\\\\my-server\\my-path-to-the-database-file \\DBtest.accdb";

$sql = "SELECT MyLongText FROM Table1";

$pdo = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=".$dbFile.";Uid=; Pwd=;ExtendedAnsiSQL=1;");
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$result = $pdo->query($sql);
$row = $result->fetchColumn(0);
	
echo "var_dump of PDO: ";
var_dump($row);

echo "<br>";
echo "<br>";
	
$conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$dbFile","", "");
$query = odbc_exec($conn, $sql);
while($row1 = odbc_fetch_array($query)){
	echo "var_dump of odbc_connect: ";
	var_dump($row1["MyLongText"]);
}

Resulted in this output:

var_dump of PDO: string(4100) "______<more underscore>______�� ��fA��8�fA��_______<more underscore>_______"

var_dump of odbc_connect: string(2050) "______<more undescore>_______"

But I expected this output instead:

var_dump of PDO: string(2050) "______<more underscore>_______"

var_dump of odbc_connect: string(2050) "______<more undescore>_______"

PHP Version

8.3.12 x64 Non Thread Safe and 8.4.0 RC1 (Visual C++ Redistributable X64 (Visual C++ Redistributable for Visual Studio 2022) installed)

Operating System

Windows Server 2019 Standard, Internet Information Services (Version 10.01.17763.1) or Windows 10

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions