-
Bug
-
Resolution: Fixed
-
P4
-
1.0.2, 1.1
-
1.2beta4
-
generic, sparc
-
generic, solaris_2.5
-
Not verified
This bug was found by St.Petersburg Java SQE team (by Stanislav Avzan).
The java.io.SequenceInputStream constructors work wrong with null.
Both constructors public SequenceInputStream(Enumeration e) and
public SequenceInputStream(InputStream s1,InputStream s2) treat null
as if it were the end of sequence of streams.
So the SequenceInputStream(null,someInputStream) will return -1 (End marker)
immediately and SequenceInputStream(someEnumeration) will finish on the
first occurence of null stream in sequence.
I suppose, it would be reasonable just to ignore nulls or to throw
NullPointerException (the last one is worse - checking of all Enumeration
needed).
Here is the excerpt from the specification:
"22.8.1 public SequenceInputStream(Enumeration e)
This constructor initializes a newly created SequenceInputStream by
remembering the argument, which must be an Enumeration (p.21.1) that
produces objects whose run-time type is InputStream (p.22.3). The input
streams that are produced by the enumeration will be read, in order, to
provide the bytes to be read from this SequenceInputStream. After each
input stream from the enumeration is exhausted, it is closed by calling its
close method.
22.8.2 public SequenceInputStream(InputStream s1, InputStream s2)
This constructor initializes a newly created SequenceInputStream by
remembering the two arguments, which will be read in order, first s1 and
then s2, to provide the bytes to be read from this SequenceInputStream."
As seen from the specs, null parameter isn't mentioned.
And here is the test example:
-----Test.java----------------
import java.io.*;
public class Test {
public static void main( String[] argv ) {
StringBufferInputStream is = new StringBufferInputStream("\0");
try {
SequenceInputStream sis = new SequenceInputStream(null,is);
int b = sis.read(); // either
System.out.println("Here shouldn't be -1: "+b);
} catch(NullPointerException e) {
System.out.println("Test passed (maybe): NullPointerException thrown");
} catch(Throwable e) {
System.out.println("Test failed: unexpected <"+e+"> thrown");
}
}
}
-----Output-------------------
Here shouldn't be -1: -1
------------------------------
Date: Fri, 12 Dec 1997 15:47:44 -0800 (PST)
From: Kirk Chen <Kirk.Chen@Eng>
It appears that if you construct
sis = SequenceInputStream(InputStream in1, InputStream in2)
and if in1 is null, then sis is empty, even though in2 may have bytes
available to be read. However, if in1 is not empty but in2 is null,
sis will be able to read from in1. Here's the code segment that
illustrates this:
import java.io.*;
public class TestSeqIS {
public static void main(String[] args) throws IOException {
FileInputStream fis;
try {
fis = new FileInputStream(args[0]);
} catch (IOException ex) {
fis = null;
}
SequenceInputStream seqis = new SequenceInputStream(fis, System.in);
BufferedReader in = new BufferedReader(new InputStreamReader(seqis));
String line;
while ((line = in.readLine()) != null) {
System.out.println("got: "+line);
}
}
}
it would be nice when in1 is null, SequenceInputStream will make bytes
available from in2 only, instead of just returning eof when read
against.
The java.io.SequenceInputStream constructors work wrong with null.
Both constructors public SequenceInputStream(Enumeration e) and
public SequenceInputStream(InputStream s1,InputStream s2) treat null
as if it were the end of sequence of streams.
So the SequenceInputStream(null,someInputStream) will return -1 (End marker)
immediately and SequenceInputStream(someEnumeration) will finish on the
first occurence of null stream in sequence.
I suppose, it would be reasonable just to ignore nulls or to throw
NullPointerException (the last one is worse - checking of all Enumeration
needed).
Here is the excerpt from the specification:
"22.8.1 public SequenceInputStream(Enumeration e)
This constructor initializes a newly created SequenceInputStream by
remembering the argument, which must be an Enumeration (p.21.1) that
produces objects whose run-time type is InputStream (p.22.3). The input
streams that are produced by the enumeration will be read, in order, to
provide the bytes to be read from this SequenceInputStream. After each
input stream from the enumeration is exhausted, it is closed by calling its
close method.
22.8.2 public SequenceInputStream(InputStream s1, InputStream s2)
This constructor initializes a newly created SequenceInputStream by
remembering the two arguments, which will be read in order, first s1 and
then s2, to provide the bytes to be read from this SequenceInputStream."
As seen from the specs, null parameter isn't mentioned.
And here is the test example:
-----Test.java----------------
import java.io.*;
public class Test {
public static void main( String[] argv ) {
StringBufferInputStream is = new StringBufferInputStream("\0");
try {
SequenceInputStream sis = new SequenceInputStream(null,is);
int b = sis.read(); // either
System.out.println("Here shouldn't be -1: "+b);
} catch(NullPointerException e) {
System.out.println("Test passed (maybe): NullPointerException thrown");
} catch(Throwable e) {
System.out.println("Test failed: unexpected <"+e+"> thrown");
}
}
}
-----Output-------------------
Here shouldn't be -1: -1
------------------------------
Date: Fri, 12 Dec 1997 15:47:44 -0800 (PST)
From: Kirk Chen <Kirk.Chen@Eng>
It appears that if you construct
sis = SequenceInputStream(InputStream in1, InputStream in2)
and if in1 is null, then sis is empty, even though in2 may have bytes
available to be read. However, if in1 is not empty but in2 is null,
sis will be able to read from in1. Here's the code segment that
illustrates this:
import java.io.*;
public class TestSeqIS {
public static void main(String[] args) throws IOException {
FileInputStream fis;
try {
fis = new FileInputStream(args[0]);
} catch (IOException ex) {
fis = null;
}
SequenceInputStream seqis = new SequenceInputStream(fis, System.in);
BufferedReader in = new BufferedReader(new InputStreamReader(seqis));
String line;
while ((line = in.readLine()) != null) {
System.out.println("got: "+line);
}
}
}
it would be nice when in1 is null, SequenceInputStream will make bytes
available from in2 only, instead of just returning eof when read
against.