aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2001-07-13 05:41:28 +0000
committerTom Tromey <tromey@gcc.gnu.org>2001-07-13 05:41:28 +0000
commita9a399fe24303d933a412f01c01bb8e78d97cf9f (patch)
tree4aff078d910dc63cd6e5522da1dc415bc661bb0c /libjava
parentc813baa415260f431f2a5c67312338802cbe5671 (diff)
downloadgcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.zip
gcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.tar.gz
gcc-a9a399fe24303d933a412f01c01bb8e78d97cf9f.tar.bz2
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
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog12
-rw-r--r--libjava/gnu/gcj/convert/natIconv.cc14
-rw-r--r--libjava/java/io/BufferedInputStream.java4
-rw-r--r--libjava/java/io/InputStreamReader.java117
4 files changed, 83 insertions, 64 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 5a815b9c..017a99a 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,4 +1,16 @@
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>
Report from Henner Zeller:
* java/io/FileOutputStream.java (FileOutputStream): Throw
diff --git a/libjava/gnu/gcj/convert/natIconv.cc b/libjava/gnu/gcj/convert/natIconv.cc
index d346b14..3c5f52e 100644
--- a/libjava/gnu/gcj/convert/natIconv.cc
+++ b/libjava/gnu/gcj/convert/natIconv.cc
@@ -1,6 +1,6 @@
// 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.
@@ -17,8 +17,11 @@ details. */
#include <gnu/gcj/convert/Input_iconv.h>
#include <gnu/gcj/convert/Output_iconv.h>
+#include <java/io/CharConversionException.h>
#include <java/io/UnsupportedEncodingException.h>
+#include <errno.h>
+
#ifdef HAVE_ICONV
#include <iconv.h>
@@ -84,7 +87,14 @@ gnu::gcj::convert::Input_iconv::read (jcharArray outbuffer,
size_t r = iconv_adapter (iconv, (iconv_t) handle,
&inbuf, &inavail,
&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)
{
diff --git a/libjava/java/io/BufferedInputStream.java b/libjava/java/io/BufferedInputStream.java
index 6473854..15fa936 100644
--- a/libjava/java/io/BufferedInputStream.java
+++ b/libjava/java/io/BufferedInputStream.java
@@ -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.
@@ -131,7 +131,7 @@ public class BufferedInputStream extends FilterInputStream
return origN - n;
}
- private boolean refill() throws IOException
+ boolean refill() throws IOException
{
if (markpos < 0)
count = pos = 0;
diff --git a/libjava/java/io/InputStreamReader.java b/libjava/java/io/InputStreamReader.java
index 03a0c3e..45fd598 100644
--- a/libjava/java/io/InputStreamReader.java
+++ b/libjava/java/io/InputStreamReader.java
@@ -44,6 +44,11 @@ public class InputStreamReader extends Reader
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
? (BufferedInputStream) in
: new BufferedInputStream(in);
@@ -76,28 +81,11 @@ public class InputStreamReader extends Reader
if (wpos < wcount)
return true;
- if (work == null)
- {
- work = new char[100];
- wpos = 0;
- wcount = 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;
- }
+
+ // According to the spec, an InputStreamReader is ready if its
+ // input buffer is not empty (above), or if bytes are
+ // available on the underlying byte stream.
+ return in.available () > 0;
}
}
@@ -108,33 +96,23 @@ public class InputStreamReader extends Reader
if (in == null)
throw new IOException("Stream closed");
+ if (length == 0)
+ return 0;
+
int wavail = wcount - wpos;
- if (wavail > 0)
- {
- if (length > wavail)
- length = wavail;
- System.arraycopy(work, wpos, buf, offset, length);
- wpos += length;
- return length;
- }
- else
+ if (wavail <= 0)
{
- 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;
- }
+ // Nothing waiting, so refill our buffer.
+ if (! refill ())
+ return -1;
+ wavail = wcount - wpos;
}
+
+ if (length > wavail)
+ length = wavail;
+ System.arraycopy(work, wpos, buf, offset, length);
+ wpos += length;
+ return length;
}
}
@@ -146,24 +124,43 @@ public class InputStreamReader extends Reader
throw new IOException("Stream closed");
int wavail = wcount - wpos;
- if (wavail > 0)
- return work[wpos++];
- if (work == null)
+ if (wavail <= 0)
{
- work = new char[100];
- wpos = 0;
- wcount = 0;
+ // Nothing waiting, so refill our buffer.
+ if (! refill ())
+ return -1;
}
- else if (wavail == 0)
+
+ 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)
{
- wpos = 0;
- wcount = 0;
+ wcount += count;
+ return true;
}
- int count = read(work, wpos, work.length-wpos);
- if (count <= 0)
- return -1;
- wcount = wpos + count;
- return work[wpos++];
}
}
}