Skip to Content.
Sympa Menu

freetds - Re: PHP's mssql_fetch_row inserting '\0' on strings ?

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Lowden, James K" <LowdenJK AT bernstein.com>
  • To: "'TDS Development Group'" <freetds AT franklin.metalab.unc.edu>
  • Subject: Re: PHP's mssql_fetch_row inserting '\0' on strings ?
  • Date: Thu, 20 Jun 2002 16:07:36 -0400

> From: Andre Costa [mailto:brblueser AT uol.com.br]
> Sent: June 20, 2002 2:13 PM

> Bingo! Nice shot =) Yes, resultant data with embedded \0s is twice the
> size of the "right" data. So, this proves the assumptions
> that UCS-2 vs.
> ASCII is the source of the confusion, doesn't it? Maybe PHP
> is allocating
> a buffer for UCS-2 data and is indeed receiving ASCII?
>
> Looks like we're narrowing the probl down =)

I think it's our problem. In fact, I think it's a libtds error.

I wrote a little utility (attached) to display informtion about column
descriptors on a result set. Here's what I see:

$ ./dbsql -U LowdenJK -S spquant -p <hi
select cast( 'hello' as nvarchar(20) ) as hi
1 columns returned.

column_name: hi
column_type: 47
column_size: 40
length: 10
data (first word): 0x6c6c6568

There are two surprising things about this:

1. Why is the datatype 47? I expected 39, see below.
2 The first work of the buffer pointed to by dbdata() is 0x6c6c6568
('lleh')? Isn't it odd the high bytes aren't zero? This is supposed to be
a UCS-2 buffer!

Hypothesis: When we return an unreconstructed UCS-2 buffer, we goof. We
convert it to ASCII, and return that type, and don't set the length
correctly. :(

What I'm seeing is consistent with what PHP would be getting from us, if PHP
is not binding the nchar/nvarchar data to strings, but is taking our buffer
verbatim. I don't know what they'd want to with UCS-2 encoded text, but
that's another question. They might not be thinking about UCS-2 at all.
They might see 47, think "ascii string, length 10" and go from there. I
would.

Based on the table below, I can't see how a dblib client could determine the
column is UCS-2 data, even if we did it "right". AFAIK, dblib and ODBC have
no non-BCP function that distinguishes between UCS-2 and ASCII. Broken at
the vendor, I'd say.

--jkl

1> select cast(name as varchar(30)), type, xtype, usertype, xusertype from
systypes where name like '%char%' order by xtype
2> go
type xtype usertype xusertype
------------------------------ ---- ----- -------- ---------
varchar 39 167 2 167
char 47 175 1 175
nvarchar 39 231 0 231
nchar 47 239 0 239

(4 rows affected)

Attachment: dbsql.c
Description: Binary data

Attachment: eg_handlers.h
Description: Binary data




Archive powered by MHonArc 2.6.24.

Top of Page