Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sqlsrv_fetch_object modifies full qualified class names #119

Closed
xalopp opened this issue Aug 1, 2016 · 3 comments
Closed

sqlsrv_fetch_object modifies full qualified class names #119

xalopp opened this issue Aug 1, 2016 · 3 comments

Comments

@xalopp
Copy link

xalopp commented Aug 1, 2016

sqlsrv_fetch_object modifies the full qualified class names of the supplied class.

The following PHP Code

<?php

namespace Doctrine\Tests\DBAL\Functional;

class A {
    public $accountNumber;
}

$idx = array_search(__NAMESPACE__.'\\A',get_declared_classes());
echo "orig class ".__NAMESPACE__.'\\A'." exits: ".(class_exists(__NAMESPACE__.'\\A')?'yes':'no').PHP_EOL;
echo "lower class ".strtolower(__NAMESPACE__.'\\A')." exits: ".(class_exists(strtolower(__NAMESPACE__.'\\A'))?'yes':'no').PHP_EOL;
echo 'BEFORE:  '.get_declared_classes()[$idx].PHP_EOL;

$serverName        = "192.168.123.41";
$connectionOptions = ["Database" => "AdventureWorks2016CTP3", "Uid" => "test", "PWD" => 'test'];

$conn = sqlsrv_connect( $serverName, $connectionOptions);
if($conn === false) {
    die(print_r(sqlsrv_errors(), true));
}

$sql = "SELECT [AccountNumber] FROM Sales.Customer";
$stmt = sqlsrv_query( $conn, $sql);
if($stmt === false ) {
    die(print_r(sqlsrv_errors(), true));
}

$obj = sqlsrv_fetch_object($stmt, __NAMESPACE__.'\\A');

echo "orig class ".__NAMESPACE__.'\\A'." exits: ".(class_exists(__NAMESPACE__.'\\A')?'yes':'no').PHP_EOL;
echo "lower class ".strtolower(__NAMESPACE__.'\\A')." exits: ".(class_exists(strtolower(__NAMESPACE__.'\\A'))?'yes':'no').PHP_EOL;
echo 'AFTER:  '.get_declared_classes()[$idx].PHP_EOL;

produces on Ubuntu 16.04 PHP 7.0.9-1+deb.sury.org~xenial+1 (cli) ( NTS ) with sqlsrv driver version 4.0.2 following output:

orig class Doctrine\Tests\DBAL\Functional\A exits: yes
lower class doctrine\tests\dbal\functional\a exits: yes
BEFORE:  Doctrine\Tests\DBAL\Functional\A
orig class Doctrine\Tests\DBAL\Functional\A exits: no
lower class doctrine\tests\dbal\functional\a exits: yes
AFTER:  doctrine\tests\dbal\functional\a

as you can see, the full qualified class name changed completely to lowercase and class_exists is unable to find the class with its original name! 😵

Unfortunately, the source code of the Linux version isn't release yet, but I'm persuaded that the bug also exists on Windows, for PHP5 and PHP7.

I suspect the line https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L797 is causing the problem, because the lowercase class name is create here and used in https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L825 to instantiate the corresponding object.

Since zend_lookup_class which is called in https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L816 is using the lower cased class name internally, it's not required to call it with a lower cased class name.

I would recommend to use in sqlsrv_fetch_object the class name, spelled as returned from get_declared_classes.

@xalopp
Copy link
Author

xalopp commented Aug 1, 2016

$obj = sqlsrv_fetch_object($stmt, 'Exception');

throw new \Exception("fail");

will produce a nice segmentation fault 🎉

@meet-bhagdev
Copy link
Contributor

@xalopp good catch. We will look into this to see what is going on. Will keep you posted.

@meet-bhagdev
Copy link
Contributor

Fixed by #147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants