xmlgraphics-batik-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Viliam Durina (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (BATIK-963) ArrayIndexOutOfBounds in AbstractWMFPainter with 1-bit color images
Date Wed, 22 Jan 2014 07:25:19 GMT

    [ https://issues.apache.org/jira/browse/BATIK-963?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13878355#comment-13878355
] 

Viliam Durina commented on BATIK-963:
-------------------------------------

Thanks. The project, where I found this bug, never got into production, but I was sad this
was not applied...

> ArrayIndexOutOfBounds in AbstractWMFPainter with 1-bit color images
> -------------------------------------------------------------------
>
>                 Key: BATIK-963
>                 URL: https://issues.apache.org/jira/browse/BATIK-963
>             Project: Batik
>          Issue Type: Bug
>          Components: Utilities
>    Affects Versions: 1.8
>         Environment: Operating System: All
> Platform: All
>            Reporter: a6537691
>            Assignee: Batik Developer's Mailing list
>         Attachments: bug_50056_patch.diff, failingfile.wmf, obrazok2_orig.wmf
>
>
> I use WMFTranscoder to convert WMF files to SVG. I found a image, that fails with following
exception:
> java.lang.ArrayIndexOutOfBoundsException: 108248
> 	at org.apache.batik.transcoder.wmf.tosvg.AbstractWMFPainter.getImage(AbstractWMFPainter.java:194)
> 	at org.apache.batik.transcoder.wmf.tosvg.AbstractWMFPainter.getImage(AbstractWMFPainter.java:74)
> 	at org.apache.batik.transcoder.wmf.tosvg.WMFPainter.paint(WMFPainter.java:859)
> 	at org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder.transcode(WMFTranscoder.java:187)
> 	...
> The length of the array that caused the exception was 108248, so 1 byte after the end
was attempted to read.
> The problem was on line 194 in AbstractWMFPainter, where next byte for the next iteration,
which could be after the end, if there is no padding.
> Here is fixed code for the getImage(byte[]) method:
> /** Return the image associated with a bitmap in a Metafile.
>      *  24 bits and 8 bits bitmaps are handled.
>      *  @param bit the bitmap byte array
>      *  @return the Image associated with the bitmap (null if the dimensions detected
in the
>      *     header are not consistent with the assumed dimensions)
>      */
>     protected BufferedImage getImage(byte[] bit) {
>         // get the header of the bitmap, first the width and height
>         int _width = (((int)bit[7] & 0x00ff) << 24) | (((int)bit[6] & 0x00ff)
<< 16)
>                     | (((int)bit[5] & 0x00ff) << 8) | (int)bit[4] & 0x00ff;
>         int _height = (((int)bit[11] & 0x00ff) << 24) | (((int)bit[10] &
0x00ff) << 16)
>                     | (((int)bit[9] & 0x00ff) << 8) | (int)bit[8] & 0x00ff;
>         // OK, we can safely create the data array now
>         int[] bitI = new int[_width * _height];
>         BufferedImage img = new BufferedImage(_width, _height, BufferedImage.TYPE_INT_RGB);
>         WritableRaster raster = img.getRaster();
>         // retrieve useful informations in bitmap header
>         // size of header
>         int _headerSize = (((int)bit[3] & 0x00ff) << 24) | (((int)bit[2] &
0x00ff)<<16)
>                             | (((int)bit[1] & 0x00ff) << 8) | (int)bit[0] &
0x00ff;
>         // number of planes
>         int _planes = (((int)bit[13] & 0x00ff) << 8) | (int)bit[12] & 0x00ff;
>         // number of bits per pixel
>         int _nbit = (((int)bit[15] & 0x00ff) << 8) | (int)bit[14] & 0x00ff;
>         // compression factor : unused
>         // size of the image
>         int _size = (((int)bit[23] & 0x00ff) << 24) | (((int)bit[22] &
0x00ff) << 16)
>                         | (((int)bit[21] & 0x00ff) << 8) | (int)bit[20] &
0x00ff;
>         // infer the size of image if it is not given in the file
>         if (_size == 0) _size = ((((_width * _nbit) + 31) & ~31 ) >> 3) * _height;
>         // number of used colors
>         int _clrused = (((int)bit[35] & 0x00ff) << 24) | (((int)bit[34]&0x00ff)
<< 16)
>                         | (((int)bit[33] & 0x00ff) << 8) | (int)bit[32]&0x00ff;
>         // 24 bit image
>         if (_nbit == 24) {
>             // read the scan lines
>             int pad = (_size / _height) - _width * 3;
>             int offset = _headerSize; // begin to read data after header
>             // populate the int array
>             for (int j = 0; j < _height; j++) {
>                 for (int i = 0; i < _width; i++) {
>                     bitI[_width * (_height - j - 1) + i] =
>                         (255 & 0x00ff) << 24 | (((int)bit[offset+2] & 0x00ff)
<< 16)
>                         | (((int)bit[offset+1] & 0x00ff) << 8) | (int)bit[offset]
& 0x00ff;
>                     offset += 3;
>                 }
>                 offset += pad;
>             }
>         // 8 bit image
>         } else if (_nbit == 8) {
>             // Determine the number of colors
>             int nbColors = 0;
>             if (_clrused > 0) nbColors = _clrused;
>             else nbColors = (1 & 0x00ff) << 8;
>             // Read the palette colors.
>             int offset = _headerSize;
>             int[]  palette = new int[nbColors];
>             for (int i = 0; i < nbColors; i++) {
>                 palette[i] = (255 & 0x00ff) << 24 | (((int)bit[offset+2] &
0x00ff) << 16)
>                             | (((int)bit[offset+1] & 0x00ff) << 8)
>                             | (int)bit[offset] & 0x00ff;
>                 offset += 4;
>             }
>             // populate the int array
>             /* need to recalculate size because the offset used for palette must be substracted
>              * to overall size, else we will go after the end of the byte array...
>              */
>             _size = bit.length - offset;
>             int pad = (_size / _height) - _width;
>             for (int j = 0; j < _height; j++) {
>                 for (int i = 0; i < _width; i++) {
>                     bitI[_width*(_height-j-1)+i] = palette [((int)bit[offset] & 0x00ff)];
>                     offset++;
>                 }
>                 offset += pad;
>             }
>         // black and white image
>         } else if (_nbit == 1) {
>             // 2 colors only (black and white image)
>             int nbColors = 2;
>             // Read the palette colors.
>             int offset = _headerSize;
>             int[]  palette = new int[nbColors];
>             for (int i = 0; i < nbColors; i++) {
>                 palette[i] = (255 & 0x00ff) << 24 | (((int)bit[offset+2] &
0x00ff) << 16)
>                             | (((int)bit[offset+1] & 0x00ff) << 8)
>                             | (int)bit[offset] & 0x00ff;
>                 offset += 4;
>             }
>             // populate the int array : each pixel corresponds to a bit in the byte array
>             int pos = 7;
>             byte currentByte = bit[offset];
>             // padded to long words
>             int pad = (_size / _height) - _width/8;
>             for (int j = 0; j < _height; j++) {
>                 for (int i = 0; i < _width; i++) {
>                     if ((currentByte & (1 << pos)) != 0) bitI[_width*(_height-j-1)+i]
= palette[1];
>                     else bitI[_width*(_height-j-1)+i] = palette[0];
>                     pos--;
>                     if (pos == -1) {
>                         pos = 7;
>                         offset++;
>                         if (offset < bit.length)
>                         	currentByte = bit[offset];
>                     }
>                 }
>                 offset +=pad;
>                 pos = 7;
>                 if (offset < bit.length) currentByte = bit[offset];
>             }
>         }
>         raster.setDataElements(0, 0, _width, _height, bitI);
>         return img;
>     }



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-dev-help@xmlgraphics.apache.org


Mime
View raw message