Skip to content

Commit 86104df

Browse files
author
Anton Nashatyrev
committed
8038000: java.awt.image.RasterFormatException: Incorrect scanline stride
Reviewed-by: bae, serb
1 parent df3fb56 commit 86104df

File tree

7 files changed

+255
-16
lines changed

7 files changed

+255
-16
lines changed

jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,10 +755,22 @@ private void verify() {
755755
+ scanlineStride);
756756
}
757757

758-
for (int i = 0; i < data.length; i++) {
759-
if (scanlineStride > data[i].length) {
760-
throw new RasterFormatException("Incorrect scanline stride: "
761-
+ scanlineStride);
758+
if ((long)minX - sampleModelTranslateX < 0 ||
759+
(long)minY - sampleModelTranslateY < 0) {
760+
761+
throw new RasterFormatException("Incorrect origin/translate: (" +
762+
minX + ", " + minY + ") / (" +
763+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
764+
}
765+
766+
767+
if (height > 1 || minY - sampleModelTranslateY > 0) {
768+
// buffer should contain at least one scanline
769+
for (int i = 0; i < data.length; i++) {
770+
if (scanlineStride > data[i].length) {
771+
throw new RasterFormatException("Incorrect scanline stride: "
772+
+ scanlineStride);
773+
}
762774
}
763775
}
764776

jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -885,15 +885,31 @@ protected final void verify() {
885885
}
886886
}
887887

888+
if ((long)minX - sampleModelTranslateX < 0 ||
889+
(long)minY - sampleModelTranslateY < 0) {
890+
891+
throw new RasterFormatException("Incorrect origin/translate: (" +
892+
minX + ", " + minY + ") / (" +
893+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
894+
}
895+
888896
// we can be sure that width and height are greater than 0
889897
if (scanlineStride < 0 ||
890-
scanlineStride > (Integer.MAX_VALUE / height) ||
891-
scanlineStride > data.length)
898+
scanlineStride > (Integer.MAX_VALUE / height))
892899
{
893900
// integer overflow
894901
throw new RasterFormatException("Incorrect scanline stride: "
895902
+ scanlineStride);
896903
}
904+
905+
if (height > 1 || minY - sampleModelTranslateY > 0) {
906+
// buffer should contain at least one scanline
907+
if (scanlineStride > data.length) {
908+
throw new RasterFormatException("Incorrect scanline stride: "
909+
+ scanlineStride);
910+
}
911+
}
912+
897913
int lastScanOffset = (height - 1) * scanlineStride;
898914

899915
if (pixelStride < 0 ||

jdk/src/share/classes/sun/awt/image/BytePackedRaster.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,13 +1386,28 @@ private void verify (boolean strictCheck) {
13861386
throw new RasterFormatException("Invalid raster dimension");
13871387
}
13881388

1389+
if ((long)minX - sampleModelTranslateX < 0 ||
1390+
(long)minY - sampleModelTranslateY < 0) {
1391+
1392+
throw new RasterFormatException("Incorrect origin/translate: (" +
1393+
minX + ", " + minY + ") / (" +
1394+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
1395+
}
1396+
13891397
if (scanlineStride < 0 ||
1390-
scanlineStride > (Integer.MAX_VALUE / height) ||
1391-
scanlineStride > data.length)
1398+
scanlineStride > (Integer.MAX_VALUE / height))
13921399
{
13931400
throw new RasterFormatException("Invalid scanline stride");
13941401
}
13951402

1403+
if (height > 1 || minY - sampleModelTranslateY > 0) {
1404+
// buffer should contain at least one scanline
1405+
if (scanlineStride > data.length) {
1406+
throw new RasterFormatException("Incorrect scanline stride: "
1407+
+ scanlineStride);
1408+
}
1409+
}
1410+
13961411
int lastbit = (dataBitOffset
13971412
+ (height-1) * scanlineStride * 8
13981413
+ (width-1) * pixelBitStride

jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,15 +654,31 @@ protected final void verify() {
654654
") must be >= 0");
655655
}
656656

657+
if ((long)minX - sampleModelTranslateX < 0 ||
658+
(long)minY - sampleModelTranslateY < 0) {
659+
660+
throw new RasterFormatException("Incorrect origin/translate: (" +
661+
minX + ", " + minY + ") / (" +
662+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
663+
}
664+
657665
// we can be sure that width and height are greater than 0
658666
if (scanlineStride < 0 ||
659-
scanlineStride > (Integer.MAX_VALUE / height) ||
660-
scanlineStride > data.length)
667+
scanlineStride > (Integer.MAX_VALUE / height))
661668
{
662669
// integer overflow
663670
throw new RasterFormatException("Incorrect scanline stride: "
664671
+ scanlineStride);
665672
}
673+
674+
if (height > 1 || minY - sampleModelTranslateY > 0) {
675+
// buffer should contain at least one scanline
676+
if (scanlineStride > data.length) {
677+
throw new RasterFormatException("Incorrect scanline stride: "
678+
+ scanlineStride);
679+
}
680+
}
681+
666682
int lastScanOffset = (height - 1) * scanlineStride;
667683

668684
if (pixelStride < 0 ||

jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,21 @@ private void verify() {
754754
+ scanlineStride);
755755
}
756756

757-
for (int i = 0; i < data.length; i++) {
758-
if (scanlineStride > data[i].length) {
759-
throw new RasterFormatException("Incorrect scanline stride: "
760-
+ scanlineStride);
757+
if ((long)minX - sampleModelTranslateX < 0 ||
758+
(long)minY - sampleModelTranslateY < 0) {
759+
760+
throw new RasterFormatException("Incorrect origin/translate: (" +
761+
minX + ", " + minY + ") / (" +
762+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
763+
}
764+
765+
if (height > 1 || minY - sampleModelTranslateY > 0) {
766+
// buffer should contain at least one scanline
767+
for (int i = 0; i < data.length; i++) {
768+
if (scanlineStride > data[i].length) {
769+
throw new RasterFormatException("Incorrect scanline stride: "
770+
+ scanlineStride);
771+
}
761772
}
762773
}
763774

jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,15 +819,31 @@ protected final void verify() {
819819
}
820820
}
821821

822+
if ((long)minX - sampleModelTranslateX < 0 ||
823+
(long)minY - sampleModelTranslateY < 0) {
824+
825+
throw new RasterFormatException("Incorrect origin/translate: (" +
826+
minX + ", " + minY + ") / (" +
827+
sampleModelTranslateX + ", " + sampleModelTranslateY + ")");
828+
}
829+
822830
// we can be sure that width and height are greater than 0
823831
if (scanlineStride < 0 ||
824-
scanlineStride > (Integer.MAX_VALUE / height) ||
825-
scanlineStride > data.length)
832+
scanlineStride > (Integer.MAX_VALUE / height))
826833
{
827834
// integer overflow
828835
throw new RasterFormatException("Incorrect scanline stride: "
829836
+ scanlineStride);
830837
}
838+
839+
if (height > 1 || minY - sampleModelTranslateY > 0) {
840+
// buffer should contain at least one scanline
841+
if (scanlineStride > data.length) {
842+
throw new RasterFormatException("Incorrect scanline stride: "
843+
+ scanlineStride);
844+
}
845+
}
846+
831847
int lastScanOffset = (height - 1) * scanlineStride;
832848

833849
if (pixelStride < 0 ||
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8038000
27+
*
28+
* @summary Verifies that we could create different type of Rasters with height 1
29+
* and strideline which exceeds raster width.
30+
* Also checks that a set of RasterOp work correctly with such kind of Rasters.
31+
*
32+
* @run main bug8038000
33+
*/
34+
35+
import java.awt.*;
36+
import java.awt.color.ColorSpace;
37+
import java.awt.geom.AffineTransform;
38+
import java.awt.image.*;
39+
import java.util.Arrays;
40+
41+
public class bug8038000 {
42+
43+
public static void main(String[] args) throws Exception {
44+
new bug8038000().checkOps();
45+
46+
// No exceptions - Passed
47+
}
48+
49+
private void checkOps() throws Exception {
50+
51+
RasterOp[] ops = new RasterOp[] {
52+
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB),
53+
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), null),
54+
new AffineTransformOp(AffineTransform.getScaleInstance(1, 1.1), null)
55+
};
56+
57+
58+
for (RasterOp op: ops) {
59+
// Banded rasters
60+
checkOp(Raster.createBandedRaster(DataBuffer.TYPE_BYTE, 10, 1, 10,
61+
new int[] {0, 1, 2}, new int[]{2,1,0}, null),
62+
Raster.createBandedRaster(DataBuffer.TYPE_BYTE, 10, 1, 1001,
63+
new int[] {0, 1, 2}, new int[]{2,1,0}, null), op);
64+
checkOp(Raster.createBandedRaster(DataBuffer.TYPE_USHORT, 10, 1, 10,
65+
new int[] {0, 1, 2}, new int[]{2,1,0}, null),
66+
Raster.createBandedRaster(DataBuffer.TYPE_USHORT, 10, 1, 1001,
67+
new int[] {0, 1, 2}, new int[]{2,1,0}, null), op);
68+
checkOp(Raster.createBandedRaster(DataBuffer.TYPE_INT, 10, 1, 10,
69+
new int[] {0, 1, 2}, new int[]{2,1,0}, null),
70+
Raster.createBandedRaster(DataBuffer.TYPE_INT, 10, 1, 1001,
71+
new int[] {0, 1, 2}, new int[]{2,1,0}, null), op);
72+
73+
// Interleaved rasters
74+
checkOp(Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
75+
10, 1, 30, 3, new int[]{0, 1, 2}, null),
76+
Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
77+
10, 1, 1001, 3, new int[]{0, 1, 2}, null),
78+
op);
79+
80+
checkOp(Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
81+
10, 1, 30, 3, new int[]{0, 1, 2}, null),
82+
Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
83+
10, 1, 1001, 3, new int[]{0, 1, 2}, null),
84+
op);
85+
86+
// Packed rasters
87+
checkOp(Raster.createPackedRaster(new DataBufferByte(10), 10, 1, 10,
88+
new int[] {0x01, 0x02, 0x04}, null),
89+
Raster.createPackedRaster(new DataBufferByte(10), 10, 1, 2000,
90+
new int[] {0x01, 0x02, 0x04}, null),
91+
op);
92+
checkOp(Raster.createPackedRaster(new DataBufferInt(10), 10, 1, 10,
93+
new int[] {0xff0000, 0x00ff00, 0x0000ff}, null),
94+
Raster.createPackedRaster(new DataBufferInt(10), 10, 1, 20,
95+
new int[] {0xff0000, 0x00ff00, 0x0000ff}, null),
96+
op);
97+
98+
}
99+
}
100+
101+
/**
102+
* Takes two identical rasters (identical with the exception of scanline stride)
103+
* fills their pixels with identical data, applies the RasterOp to both rasters
104+
* and checks that the result is the same
105+
*/
106+
private void checkOp(WritableRaster wr1, WritableRaster wr2, RasterOp op) {
107+
System.out.println("Checking " + op + " with rasters: \n " + wr1 +
108+
"\n " + wr2);
109+
try {
110+
WritableRaster r1 = op.filter(fillRaster(wr1), null);
111+
WritableRaster r2 = op.filter(fillRaster(wr2), null);
112+
compareRasters(r1, r2);
113+
} catch (ImagingOpException e) {
114+
System.out.println(" Skip: Op is not supported: " + e);
115+
}
116+
}
117+
118+
private WritableRaster fillRaster(WritableRaster wr) {
119+
int c = 0;
120+
for(int x = wr.getMinX(); x < wr.getMinX() + wr.getWidth(); x++) {
121+
for(int y = wr.getMinY(); y < wr.getMinY() + wr.getHeight(); y++) {
122+
for (int b = 0; b < wr.getNumBands(); b++) {
123+
wr.setSample(x, y, b, c++);
124+
}
125+
}
126+
}
127+
return wr;
128+
}
129+
130+
private void compareRasters(Raster r1, Raster r2) {
131+
Rectangle bounds = r1.getBounds();
132+
if (!bounds.equals(r2.getBounds())) {
133+
throw new RuntimeException("Bounds differ.");
134+
}
135+
136+
if (r1.getNumBands() != r2.getNumBands()) {
137+
throw new RuntimeException("Bands differ.");
138+
}
139+
140+
int[] b1 = new int[r1.getNumBands()];
141+
int[] b2 = new int[r1.getNumBands()];
142+
143+
for (int x = (int) bounds.getX(); x < bounds.getMaxX(); x++) {
144+
for (int y = (int) bounds.getY(); y < bounds.getMaxY(); y++) {
145+
r1.getPixel(x,y, b1);
146+
r2.getPixel(x,y, b2);
147+
if (!Arrays.equals(b1, b2)) {
148+
throw new RuntimeException("Pixels differ.");
149+
}
150+
}
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)