Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8266435

WBMPImageReader.read() should not truncate the input stream

XMLWordPrintable

    • b27
    • x86_64
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      openjdk version "16.0.1" 2021-04-20
      OpenJDK Runtime Environment Corretto-16.0.1.9.1 (build 16.0.1+9)
      OpenJDK 64-Bit Server VM Corretto-16.0.1.9.1 (build 16.0.1+9, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      com.sun.imageio.plugins.wbmp.WBMPImageReader doesn't check the return value of read() .

      iis.read(((DataBufferByte)tile.getDataBuffer()).getData(),
                           0, height*sm.getScanlineStride());

      it should check the return value and read more, or call readFully.

      Using a third party ImageInputStream is a problem if read() reads less than expected, although this is legal.
      https://github.com/haraldk/TwelveMonkeys/issues/606

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      success

      ---------- BEGIN SOURCE ----------
      package jdk9test;


      import java.awt.Color;
      import java.awt.Graphics2D;
      import java.awt.image.BufferedImage;
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.RandomAccessFile;
      import javax.imageio.ImageIO;
      import javax.imageio.stream.ImageInputStreamImpl;


      public class WBmpBug
      {
          static final int LIMIT = 1000; // limit 32000 works
          public static void main(String[] args) throws IOException
          {
              BufferedImage bw = new BufferedImage(500, 500, BufferedImage.TYPE_BYTE_BINARY);
              Graphics2D g = (Graphics2D) bw.getGraphics();
              g.setBackground(Color.white);
              g.fillRect(0, 0, bw.getWidth(), bw.getHeight());
              g.dispose();
              boolean b = ImageIO.write(bw, "wbmp", new File("test2.wbmp"));
              assert b = true;
              BufferedImage bim2 = ImageIO.read(new LimitedImageInputStream(new File("test2.wbmp"), LIMIT));
              //BufferedImage bim2 = ImageIO.read(new File("test2.wbmp")); // this works
              b = ImageIO.write(bim2, "wbmp", new File("test3.wbmp"));
              assert b = true;
              for (int x = 0; x < bim2.getWidth(); ++x)
              {
                  for (int y = 0; y < bim2.getHeight(); ++y)
                  {
                      int i1 = bim2.getRGB(x, y);
                      int i2 = bw.getRGB(x, y);
                      if (i1 != i2)
                      {
                          System.err.println("fail");
                          System.exit(-1);
                      }
                  }
              }
              System.out.println("success");
          }
          
          static class LimitedImageInputStream extends ImageInputStreamImpl
          {
              private final RandomAccessFile raf;
              private final int limit;
              
              public LimitedImageInputStream(File file, int limit) throws FileNotFoundException
              {
                  raf = new RandomAccessFile(file, "r");
                  this.limit = limit;
              }

              @Override
              public int read() throws IOException
              {
                  return raf.read();
              }

              @Override
              public int read(byte[] b, int off, int len) throws IOException
              {
                  int readlen = raf.read(b, off, Math.min(limit, len));
                  System.out.println("readLen: " + readlen + " of " + len);
                  return readlen;
              }

              @Override
              public void close() throws IOException
              {
                  super.close();
                  raf.close();
              }

              @Override
              public void seek(long pos) throws IOException
              {
                  super.seek(pos);
                  raf.seek(pos);
              }
              
              
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      use higher buffer size (32000) or use standard classes

      FREQUENCY : always


            jdv Jayathirth D V
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: