Bug #44278 [ReO]: ODBC: nvarchar(max) mangled

From: Date: Mon, 22 Jan 2018 18:54:45 +0000
Subject: Bug #44278 [ReO]: ODBC: nvarchar(max) mangled
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-213664@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=44278&edit=1

 ID:                 44278
 Updated by:         ab@php.net
 Reported by:        ethan dot nelson at ltd dot org
 Summary:            ODBC: nvarchar(max) mangled
 Status:             Re-Opened
 Type:               Bug
 Package:            PDO ODBC
 PHP Version:        7
 Block user comment: N
 Private report:     N

 New Comment:

I see. Naturally bugfixes are checked by the tests, which is also helpful for a review and to ensure
future bugfixes don't breach existing behaviors. I was just going through some ODBC related
tickets today, so stumbled upon this one. From what is done in the second patch - it is similar to
what is going in ext/odbc. The place with the vallen < 0 is however something interesting, namely
to know, how the negative length is produced. Perhaps it needs to be done in ext/odbc, too. Anyway,
i might check your patch later then and see for tests, as we shouldn't loose the good work. Or
perhaps you'll find some time for it.

Thanks.


Previous Comments:
------------------------------------------------------------------------
[2018-01-22 17:56:46] chris at ocproducts dot com

It'd take me a few days to get back into this and to the point of writing working PDO tests, I
just don't have that kind of time I'm afraid.

------------------------------------------------------------------------
[2018-01-22 16:31:18] ab@php.net

@chris at ocproducts dot com, thanks for the patch. Could you also add some tests, please? It
concerns both nvarchar and varchar now.

Thanks.

------------------------------------------------------------------------
[2017-11-18 11:34:09] cmb@php.net

> That other bug ticket is closed

To clarify: the ticket is private.

------------------------------------------------------------------------
[2017-11-18 11:30:06] chris at ocproducts dot com

On further testing, I found my patch was mostly correct, but insufficient. There is also another
manifestation of the bug fixed in #69975, but for varchar(max) rather than nvarchar(max).

I am uploading a new patch that covers this, improves code commenting a bit, fixes a couple of
mistakes in my prior patch, and is more defensive in case SQLBindCol never runs.

This resolves my confusion re "I also got a zero value", and I now understand the
asynchronous execution relates specifically to the behaviour of SQLBindCol binding rows as the
cursor advances (previously I thought it was something to do with app responsiveness in the face of
DB latency).

This is stable for me now. I got the full Composr CMS test set passing on ODBC using SQL Server
Express 2017, with webserver on a Mac using freeTDS. This was a long journey, quite a few issues,
notably also my bug filed as #75534.

------------------------------------------------------------------------
[2017-11-17 03:34:36] chris at ocproducts dot com

That other bug ticket is closed (I think I know why), and the issue still happens in PHP7.

The issue is caused because of a bad assumption in the code - that only binary or long results
require a full SQLGetData call (as opposed to SQLBindCol). In fact, if a vallen of <=0 is
returned by reference from SQLBindCol, a SQLGetData will be required because this may mean
SQL_NO_TOTAL (-4 value for vallen). This is actually a basic memory safety issue (vallen is used for
malloc), so this is worse than just data mangling.

Certainly FreeTDS is for me using a normal VARCHAR result (not LONGVARCHAR) for VARCHAR(MAX). Hence
breaking the aforementioned assumption.

I also got a zero value for vallen when running as an Apache module, which I had to treat with
SQLGetData too. This is confusing to me, I think it may have something to do with asynchronous
execution (this is how ODBC seems to be specified) but I can't find the PHP lib even touching
that, so I'm unsure.

I have been able to fix the issue on my machine and am about to attach a patch.

Truth is this code could do with a major refactoring. There is a lot of copy and pasting, and my
patch doesn't try and solve that.

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


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=44278


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


Thread (18 messages)

« previous php.bugs (#213664) next »