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