-
Bug
-
Resolution: Fixed
-
P4
-
1.4.2
-
b17
-
x86
-
windows_2000
Name: rmT116609 Date: 05/06/2004
FULL PRODUCT VERSION :
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
FileImageOutputStream does not properly initialize the internal streamPos member when it is constructed with a RandomAccessFile that already contains data (e.g. in the case where we want ImageIO to append image data to a file with existing contents). This results in the image encoders overwriting and corrupting existing portions of the file.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached ImageRAFTest passing an image filename as argument.
You can use any image file that ImageIO can load (gif, png, jpeg).
I've attached the image from http://developers.sun.com/im/logo_java.gif
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Examine imagebroken.bin generated by the testcase. It should have the UTF string followed by PNG image data. Instead the UTF string has been corrupted by being overwritten with some image data.
ACTUAL -
Existing file data overwritten by image data. Compare to imagefix.bin generated using the workaround, the existing file data is not corrupted.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.*;
public class ImageRAFTest {
public static void main(String args[]) throws Exception {
BufferedImage image = ImageIO.read(new File(args[0]));
// FileImageOutputStream does not track streamPos properly when handed
// a RAF that already has data written to it.
RandomAccessFile raf1 = new RandomAccessFile("imagebroken.bin", "rw");
raf1.writeUTF("Some of this text is overwritten by ImageIO, the PNG should be after the bang!");
FileImageOutputStream ios = new FileImageOutputStream(raf1);
ImageIO.write(image, "PNG", ios);
ios.close();
// Fixed version using FileImageOutputStreamFix subclass
RandomAccessFile raf2 = new RandomAccessFile("imagefix.bin", "rw");
raf2.writeUTF("Some of this text is overwritten by ImageIO, the PNG should be after the bang!");
FileImageOutputStreamFix iosf = new FileImageOutputStreamFix(raf2);
ImageIO.write(image, "PNG", iosf);
iosf.close();
}
}
// FileImageOutputStream subclass that properly initializes streamPos to the
// current position in the RAF it is handed
class FileImageOutputStreamFix extends FileImageOutputStream {
public FileImageOutputStreamFix(RandomAccessFile raf) throws IOException {
super(raf);
streamPos = raf.getFilePointer();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Subclass FileImageOutputStream and initialize streamPos to raf.getFilePointer() in the constructor.
(Incident Review ID: 247205)
======================================================================
- links to
-
Commit(master) openjdk/jdk/afcad8ca
-
Review(master) openjdk/jdk/24283