Обсуждение: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and patch

Поиск
Список
Период
Сортировка

jdbc1.AbstractJdbc1Statement.setBinaryStream bug and patch

От
Martin Holz
Дата:
Hello,

org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
in postgresql 7.4.1 wrongly assumes, that
java.io.InputStream.read(byte[] b,int offset,int len )
will always read len bytes. InputStream only guarantees to
return at least 1 byte per call. The attached patch solves the bug.

Btw. setBinaryStream() should really throw an SQLException, if
in can not read as many bytes as expected from the InputStream.
Otherwise the application might silently loss data.

Regards
        Martin

--
Martin Holz     <holz@fiz-chemie.de>

Softwareentwicklung / Vernetztes Studium - Chemie
FIZ CHEMIE Berlin
Franklin Str. 11
D-10587 Berlin

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Kris Jurka
Дата:

On Wed, 7 Jan 2004, Martin Holz wrote:

> Hello,
>
> org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> in postgresql 7.4.1 wrongly assumes, that
> java.io.InputStream.read(byte[] b,int offset,int len )
> will always read len bytes. InputStream only guarantees to
> return at least 1 byte per call. The attached patch solves the bug.

Yes, it can even return 0 bytes if it feels like it.

> Btw. setBinaryStream() should really throw an SQLException, if
> in can not read as many bytes as expected from the InputStream.
> Otherwise the application might silently loss data.

The odd thing about the javadocs is that they say "The data will be read
from the stream as needed until end-of-file is reached."  The length
parameter's comment is "the number of bytes in the stream."

This is strange because it seems to imply that the length argument is just
for informational purposes and should not be used to limit the amount of
data actually read from the stream.

Kris Jurka


Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Martin Holz
Дата:
On Friday 09 January 2004 09:46, Kris Jurka wrote:
> On Wed, 7 Jan 2004, Martin Holz wrote:
> > Hello,
> >
> > org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> > in postgresql 7.4.1 wrongly assumes, that
> > java.io.InputStream.read(byte[] b,int offset,int len )
> > will always read len bytes. InputStream only guarantees to
> > return at least 1 byte per call. The attached patch solves the
> > bug.
>
> Yes, it can even return 0 bytes if it feels like it.

Only if len is 0. From javadoc:
 * If len is zero, then no bytes are read and 0 is returned;
 * otherwise, there is an attempt to read at least one byte. If no
 *  byte is available because the stream is at end of file, the value
 * -1 is returned; otherwise, at least one byte is read and stored
 * into b.

> The odd thing about the javadocs is that they say "The data will be
> read from the stream as needed until end-of-file is reached."  The
> length parameter's comment is "the number of bytes in the stream."

Don't know, which version of Javadoc you use.

http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)
seems pretty clear to me.

> This is strange because it seems to imply that the length argument
> is just for informational purposes and should not be used to limit
> the amount of data actually read from the stream.

As I read the documentation, unless len == 0, at least
1, but not more then len bytes are read.
If no input  is available the method will block. Otherwise the
method will return len bytes if possible,but less if it would
block otherwise.

Martin

--
Martin Holz     <holz@fiz-chemie.de>

Softwareentwicklung / Vernetztes Studium - Chemie
FIZ CHEMIE Berlin
Franklin Str. 11
D-10587 Berlin

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Martin Holz
Дата:
On Friday 09 January 2004 09:46, Kris Jurka wrote:
> On Wed, 7 Jan 2004, Martin Holz wrote:
> > Hello,
> >
> > org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> > in postgresql 7.4.1 wrongly assumes, that
> > java.io.InputStream.read(byte[] b,int offset,int len )
> > will always read len bytes. InputStream only guarantees to
> > return at least 1 byte per call. The attached patch solves the
> > bug.
>
> Yes, it can even return 0 bytes if it feels like it.
>
> > Btw. setBinaryStream() should really throw an SQLException, if
> > in can not read as many bytes as expected from the InputStream.
> > Otherwise the application might silently loss data.
>
> The odd thing about the javadocs is that they say "The data will be
> read from the stream as needed until end-of-file is reached."  The
> length parameter's comment is "the number of bytes in the stream."

You seem to use a other javadoc than me.
http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)
is pretty clear.

> This is strange because it seems to imply that the length argument
> is just for informational purposes and should not be used to limit
> the amount of data actually read from the stream.

At least 1 byte will be read unless len == 0. No more
than len bytes will be read. Within this limit read is
free to return as many bytes as it considers
efficient.

Martin

--
Martin Holz     <holz@fiz-chemie.de>

Softwareentwicklung / Vernetztes Studium - Chemie
FIZ CHEMIE Berlin
Franklin Str. 11
D-10587 Berlin

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Kris Jurka
Дата:
On Fri, 9 Jan 2004, Martin Holz wrote:

> On Friday 09 January 2004 09:46, Kris Jurka wrote:
>
> > The odd thing about the javadocs is that they say "The data will be
> > read from the stream as needed until end-of-file is reached."  The
> > length parameter's comment is "the number of bytes in the stream."
>
> Don't know, which version of Javadoc you use.
>
> http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)
> seems pretty clear to me.
>
> > This is strange because it seems to imply that the length argument
> > is just for informational purposes and should not be used to limit
> > the amount of data actually read from the stream.
>

I was referring to the documentation for setBinaryStream.  You mentioned
that it should throw an Exception if it couldn't read "length" bytes from
the stream.  I was commenting that our implementation might be wrong by
checking the length at all.

Kris Jurka

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Martin Holz
Дата:
On Friday 09 January 2004 17:18, Kris Jurka wrote:

> I was referring to the documentation for setBinaryStream.  You
> mentioned that it should throw an Exception if it couldn't read
> "length" bytes from the stream.  I was commenting that our
> implementation might be wrong by checking the length at all.

Sorry for not being precise. There are two different issues.
1) The way the InputStream is read is clearly wrong.
    This should be fixed.
2) What to do, when the size of the input stream does
   not match the lenght argument of Statement.setBinaryStream()
  There are two options
    a) Throw a exception
    b) Silently send all bytes, that are available.

   I don't really understand what the length argument is good for
   and think, that this is a design flaw made by Sun. I would prefer
   a), but I am not sure here.


Martin

--
Martin Holz     <holz@fiz-chemie.de>

Softwareentwicklung / Vernetztes Studium - Chemie
FIZ CHEMIE Berlin
Franklin Str. 11
D-10587 Berlin

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Kris Jurka
Дата:
On Wed, 7 Jan 2004, Martin Holz wrote:

> Hello,
>
> org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> in postgresql 7.4.1 wrongly assumes, that
> java.io.InputStream.read(byte[] b,int offset,int len )
> will always read len bytes. InputStream only guarantees to
> return at least 1 byte per call. The attached patch solves the bug.
>

I have applied a version of this patch to the cvs version on gborg.  The
setAsciiStream and setUnicodeStream methods also had this problem.  Your
patch was not quite right because it didn't correctly handle the situation
where the Stream was longer than the given length.

Kris Jurka

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Martin Holz
Дата:
Kris Jurka <books@ejurka.com> writes:

> On Wed, 7 Jan 2004, Martin Holz wrote:
>
> > Hello,
> >
> > org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> > in postgresql 7.4.1 wrongly assumes, that
> > java.io.InputStream.read(byte[] b,int offset,int len )
> > will always read len bytes. InputStream only guarantees to
> > return at least 1 byte per call. The attached patch solves the bug.
> >
>
> I have applied a version of this patch to the cvs version on gborg.  The
> setAsciiStream and setUnicodeStream methods also had this problem.

Thank you. Why does it not show up at

http://developer.postgresql.org/cvsweb.cgi/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
?

>  Your
> patch was not quite right because it didn't correctly handle the situation
> where the Stream was longer than the given length.
>
You are right.

Re: jdbc1.AbstractJdbc1Statement.setBinaryStream bug and

От
Kris Jurka
Дата:
On 16 Jan 2004, Martin Holz wrote:

> Kris Jurka <books@ejurka.com> writes:
>
> > On Wed, 7 Jan 2004, Martin Holz wrote:
> >
> > > Hello,
> > >
> > > org.postgresql.jdbc1.AbstractJdbc1Statement.setBinaryStream()
> > > in postgresql 7.4.1 wrongly assumes, that
> > > java.io.InputStream.read(byte[] b,int offset,int len )
> > > will always read len bytes. InputStream only guarantees to
> > > return at least 1 byte per call. The attached patch solves the bug.
> > >
> >
> > I have applied a version of this patch to the cvs version on gborg.  The
> > setAsciiStream and setUnicodeStream methods also had this problem.
>
> Thank you. Why does it not show up at
>
http://developer.postgresql.org/cvsweb.cgi/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
?
>

All new development of the JDBC driver has moved to gborg.postgresql.org.
With a homepage of

http://gborg.postgresql.org/project/pgjdbc/projdisplay.php

and the webcvs url you are looking for is:

http://gborg.postgresql.org/project/pgjdbc/cvs/cvs.php/pgjdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java


This patch should probably be applied to the stable version that will
remain in the 7.4 branch in the main cvs tree, but I don't have the
power to do anything about that.

Kris Jurka