re PR libgcj/3426 (java.io.InputStreamReader, infinite loop)
Fix for PR libgcj/3426: * gnu/gcj/convert/natIconv.cc: Include CharConversionException.h, errno.h. (read): Throw exception if character conversion fails. * java/io/BufferedInputStream.java (refill): Now package-private. * java/io/InputStreamReader.java (ready): Simplified. (refill): New method. (read): Use it. Co-Authored-By: David Brownell <david-b@pacbell.net> From-SVN: r43975
This commit is contained in:
parent
c813baa415
commit
a9a399fe24
4 changed files with 84 additions and 65 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2001-07-12 Tom Tromey <tromey@redhat.com>
|
||||||
|
David Brownell <david-b@pacbell.net>
|
||||||
|
|
||||||
|
Fix for PR libgcj/3426:
|
||||||
|
* gnu/gcj/convert/natIconv.cc: Include CharConversionException.h,
|
||||||
|
errno.h.
|
||||||
|
(read): Throw exception if character conversion fails.
|
||||||
|
* java/io/BufferedInputStream.java (refill): Now package-private.
|
||||||
|
* java/io/InputStreamReader.java (ready): Simplified.
|
||||||
|
(refill): New method.
|
||||||
|
(read): Use it.
|
||||||
|
|
||||||
2001-07-12 Tom Tromey <tromey@redhat.com>
|
2001-07-12 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
Report from Henner Zeller:
|
Report from Henner Zeller:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Input_iconv.java -- Java side of iconv() reader.
|
// Input_iconv.java -- Java side of iconv() reader.
|
||||||
|
|
||||||
/* Copyright (C) 2000 Free Software Foundation
|
/* Copyright (C) 2000, 2001 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -17,8 +17,11 @@ details. */
|
||||||
|
|
||||||
#include <gnu/gcj/convert/Input_iconv.h>
|
#include <gnu/gcj/convert/Input_iconv.h>
|
||||||
#include <gnu/gcj/convert/Output_iconv.h>
|
#include <gnu/gcj/convert/Output_iconv.h>
|
||||||
|
#include <java/io/CharConversionException.h>
|
||||||
#include <java/io/UnsupportedEncodingException.h>
|
#include <java/io/UnsupportedEncodingException.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
|
||||||
|
@ -84,7 +87,14 @@ gnu::gcj::convert::Input_iconv::read (jcharArray outbuffer,
|
||||||
size_t r = iconv_adapter (iconv, (iconv_t) handle,
|
size_t r = iconv_adapter (iconv, (iconv_t) handle,
|
||||||
&inbuf, &inavail,
|
&inbuf, &inavail,
|
||||||
&outbuf, &outavail);
|
&outbuf, &outavail);
|
||||||
// FIXME: what if R==-1?
|
|
||||||
|
if (r == (size_t) -1)
|
||||||
|
{
|
||||||
|
// Incomplete character.
|
||||||
|
if (errno == EINVAL)
|
||||||
|
return 0;
|
||||||
|
throw new java::io::CharConversionException ();
|
||||||
|
}
|
||||||
|
|
||||||
if (iconv_byte_swap)
|
if (iconv_byte_swap)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 1998, 1999 Free Software Foundation
|
/* Copyright (C) 1998, 1999, 2001 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ public class BufferedInputStream extends FilterInputStream
|
||||||
return origN - n;
|
return origN - n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean refill() throws IOException
|
boolean refill() throws IOException
|
||||||
{
|
{
|
||||||
if (markpos < 0)
|
if (markpos < 0)
|
||||||
count = pos = 0;
|
count = pos = 0;
|
||||||
|
|
|
@ -44,6 +44,11 @@ public class InputStreamReader extends Reader
|
||||||
|
|
||||||
private InputStreamReader(InputStream in, BytesToUnicode decoder)
|
private InputStreamReader(InputStream in, BytesToUnicode decoder)
|
||||||
{
|
{
|
||||||
|
// FIXME: someone could pass in a BufferedInputStream whose buffer
|
||||||
|
// is smaller than the longest encoded character for this
|
||||||
|
// encoding. We will probably go into an infinite loop in this
|
||||||
|
// case. We probably ought to just have our own byte buffering
|
||||||
|
// here.
|
||||||
this.in = in instanceof BufferedInputStream
|
this.in = in instanceof BufferedInputStream
|
||||||
? (BufferedInputStream) in
|
? (BufferedInputStream) in
|
||||||
: new BufferedInputStream(in);
|
: new BufferedInputStream(in);
|
||||||
|
@ -76,28 +81,11 @@ public class InputStreamReader extends Reader
|
||||||
|
|
||||||
if (wpos < wcount)
|
if (wpos < wcount)
|
||||||
return true;
|
return true;
|
||||||
if (work == null)
|
|
||||||
{
|
// According to the spec, an InputStreamReader is ready if its
|
||||||
work = new char[100];
|
// input buffer is not empty (above), or if bytes are
|
||||||
wpos = 0;
|
// available on the underlying byte stream.
|
||||||
wcount = 0;
|
return in.available () > 0;
|
||||||
}
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (in.available() <= 0)
|
|
||||||
return false;
|
|
||||||
in.mark(1);
|
|
||||||
int b = in.read();
|
|
||||||
if (b < 0)
|
|
||||||
return true;
|
|
||||||
in.reset();
|
|
||||||
converter.setInput(in.buf, in.pos, in.count);
|
|
||||||
wpos = 0;
|
|
||||||
wcount = converter.read(work, 0, work.length);
|
|
||||||
in.skip(converter.inpos - in.pos);
|
|
||||||
if (wcount > 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,34 +96,24 @@ public class InputStreamReader extends Reader
|
||||||
if (in == null)
|
if (in == null)
|
||||||
throw new IOException("Stream closed");
|
throw new IOException("Stream closed");
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
int wavail = wcount - wpos;
|
int wavail = wcount - wpos;
|
||||||
if (wavail > 0)
|
if (wavail <= 0)
|
||||||
{
|
{
|
||||||
|
// Nothing waiting, so refill our buffer.
|
||||||
|
if (! refill ())
|
||||||
|
return -1;
|
||||||
|
wavail = wcount - wpos;
|
||||||
|
}
|
||||||
|
|
||||||
if (length > wavail)
|
if (length > wavail)
|
||||||
length = wavail;
|
length = wavail;
|
||||||
System.arraycopy(work, wpos, buf, offset, length);
|
System.arraycopy(work, wpos, buf, offset, length);
|
||||||
wpos += length;
|
wpos += length;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
return 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
in.mark(1);
|
|
||||||
int b = in.read();
|
|
||||||
if (b < 0)
|
|
||||||
return -1;
|
|
||||||
in.reset();
|
|
||||||
converter.setInput(in.buf, in.pos, in.count);
|
|
||||||
int count = converter.read (buf, offset, length);
|
|
||||||
in.skip(converter.inpos - in.pos);
|
|
||||||
if (count > 0)
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read() throws IOException
|
public int read() throws IOException
|
||||||
|
@ -146,24 +124,43 @@ public class InputStreamReader extends Reader
|
||||||
throw new IOException("Stream closed");
|
throw new IOException("Stream closed");
|
||||||
|
|
||||||
int wavail = wcount - wpos;
|
int wavail = wcount - wpos;
|
||||||
if (wavail > 0)
|
if (wavail <= 0)
|
||||||
return work[wpos++];
|
|
||||||
if (work == null)
|
|
||||||
{
|
{
|
||||||
work = new char[100];
|
// Nothing waiting, so refill our buffer.
|
||||||
wpos = 0;
|
if (! refill ())
|
||||||
wcount = 0;
|
|
||||||
}
|
|
||||||
else if (wavail == 0)
|
|
||||||
{
|
|
||||||
wpos = 0;
|
|
||||||
wcount = 0;
|
|
||||||
}
|
|
||||||
int count = read(work, wpos, work.length-wpos);
|
|
||||||
if (count <= 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
wcount = wpos + count;
|
}
|
||||||
|
|
||||||
return work[wpos++];
|
return work[wpos++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read more bytes and convert them into the WORK buffer.
|
||||||
|
// Return false on EOF.
|
||||||
|
private boolean refill () throws IOException
|
||||||
|
{
|
||||||
|
wcount = wpos = 0;
|
||||||
|
|
||||||
|
if (work == null)
|
||||||
|
work = new char[100];
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// We have knowledge of the internals of BufferedInputStream
|
||||||
|
// here. Eww.
|
||||||
|
in.mark (0);
|
||||||
|
boolean r = in.refill ();
|
||||||
|
in.reset ();
|
||||||
|
if (! r)
|
||||||
|
return false;
|
||||||
|
converter.setInput(in.buf, in.pos, in.count);
|
||||||
|
int count = converter.read (work, wpos, work.length - wpos);
|
||||||
|
in.skip(converter.inpos - in.pos);
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
wcount += count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue