Package: libpgeasy
Version: 1:3.0.4-2
Severity: important

The fetch() function in libpgeasy.c copies a certain number of bytes 
into a memory location supplied by the user. Unfortunately, the 
number of bytes is that of the size of the binary object, while the
bytes themeselves are the ascii representation of the binary object
(unless BINARY CURSOR is used in the previous postgres query, and I
haven't figured out how to use that yet ..), leading to generally
speaking a short copy.

The code is (I've added some meaningfully named variables for common
subexpressions in the original code to make this clearer):

                       int arg_size = PQfsize(res, arg);

                        if (arg_size == -1)
                        {
                                int arg_len = PQgetlength(res, tuple, arg);
                                char *val = PQgetvalue(res, tuple, arg);

                                memcpy(param, val, arg_len);
                                ((char *) param)[arg_len] = NUL;
                        } else {
                                char *val = PQgetvalue(res, tuple, arg);
                                memcpy(param, val, arg_size);
                        }

and in the ELSE clause at least, if we are talking about an "integer"
type field, then the value of arg_size will be 4 (four bytes, thirty-two
bits), but the pointer returned by PQgetvalue is a text pointer:

   PQgetvalue  Returns the field (attribute) value. For most queries,
   the value returned by PQgetvalue is a null-terminated ASCII string
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   representation of the attribute value. If the query was a result of a
   BINARY cursor, then the value returned by PQgetvalue is the binary
   representation of the type in the internal format of the backend
   server. It is the programmer's responsibility to cast and convert the
   data to the correct C type. The value returned by PQgetvalue points
   to storage that is part of the PGresult structure. One must
   explicitly copy the value into other storage if it is to be used past
   the lifetime of the PGresult structure itself.

so we will generally copy only 4 bytes of a probably longer ascii string
and do no conversion, leading to a weirdo result.

I would say that BINARY CURSOR is expected in the previous query, but I
can't see any example in the docs that makes sense to me, and there's no
man page. There is an html file, and it does mention BINARY CURSOR, but
only seemingly in passing and not in any comprehensible way:

   For SELECT queries, fetch allows you to pass pointers as parameters,
   and on return the variables are filled with data from the binary
   cursor you opened.  These binary cursors cannot be used if you are
                             ^^^^^^^^^^^^^^^ what binary cursors?!!Example!
   running the pgeasy client on a system with a different architecture
   than the database server.  If you pass a NULL pointer parameter, the
   column is skipped.  fetchwithnulls allows you to retrieve the NULL
   status of the field by passing an int* after each result pointer,
   which returns true or false to indicate if the field is null.  You
   can always use libpq functions on the PGresult pointer returned by
   doquery.  reset_fetch starts the fetch back at the beginning.


 


-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.15.3
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)

Versions of packages libpgeasy depends on:
ii  libc6                       2.3.6.ds1-11 GNU C Library: Shared libraries
ii  libpq4                      8.1.8-1      PostgreSQL C client library

libpgeasy recommends no packages.

-- no debconf information


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to