undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6679308
* @summary test drawing to Alpha surfaces
*/
import java.awt.*;
import java.awt.image.*;
public class AlphaSurfaceText {
int wid=400, hgt=200;
public AlphaSurfaceText(int biType, Color c) {
BufferedImage opaquebi0 =
new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
drawText(opaquebi0, c);
BufferedImage alphabi = new BufferedImage(wid, hgt, biType);
drawText(alphabi, c);
BufferedImage opaquebi1 =
new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = opaquebi1.createGraphics();
g2d.drawImage(alphabi, 0, 0, null);
compare(opaquebi0, opaquebi1, biType, c);
}
private void drawText(BufferedImage bi, Color c) {
Graphics2D g = bi.createGraphics();
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setColor(c);
g.setFont(new Font("sansserif", Font.PLAIN, 70));
g.drawString("Hello!", 20, 100);
g.setFont(new Font("sansserif", Font.PLAIN, 12));
g.drawString("Hello!", 20, 130);
g.setFont(new Font("sansserif", Font.PLAIN, 10));
g.drawString("Hello!", 20, 150);
}
// Need to allow for minimal rounding error, so allow each component
// to differ by 1.
void compare(BufferedImage bi0, BufferedImage bi1, int biType, Color c) {
for (int x=0; x<wid; x++) {
for (int y=0; y<hgt; y++) {
int rgb0 = bi0.getRGB(x, y);
int rgb1 = bi1.getRGB(x, y);
if (rgb0 == rgb1) continue;
int r0 = (rgb0 & 0xff0000) >> 16;
int r1 = (rgb1 & 0xff0000) >> 16;
int rdiff = r0-r1; if (rdiff<0) rdiff = -rdiff;
int g0 = (rgb0 & 0x00ff00) >> 8;
int g1 = (rgb1 & 0x00ff00) >> 8;
int gdiff = g0-g1; if (gdiff<0) gdiff = -gdiff;
int b0 = (rgb0 & 0x0000ff);
int b1 = (rgb1 & 0x0000ff);
int bdiff = b0-b1; if (bdiff<0) bdiff = -bdiff;
if (rdiff > 1 || gdiff > 1 || bdiff > 1) {
throw new RuntimeException(
"Images differ for type "+biType + " col="+c +
" at x=" + x + " y="+ y + " " +
Integer.toHexString(rgb0) + " vs " +
Integer.toHexString(rgb1));
}
}
}
}
public static void main(String[] args) {
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.white);
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.red);
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.blue);
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.white);
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.red);
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.blue);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.white);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.red);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.blue);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.white);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.red);
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.blue);
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8015070
* @summary Tests for artifacts around the edges of anti-aliased text
* drawn over translucent background color.
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class AntialiasedTextArtifact {
/* Image dimensions */
private static final int TEST_IMAGE_WIDTH = 2800;
private static final int TEST_IMAGE_HEIGHT = 100;
private static final String TEST_STRING =
"The quick brown fox jumps over the lazy dog. 0123456789.";
/*
* The artifacts appear when text is drawn ontop of translucent
* background. In other words, a background with alpha channel.
* Hence we test the algorithm for image types that contain either
* straight alpha channel or pre-multiplied alpha channel. In
* addition we test the images with other common pixel formats.
*/
private static final int[] TYPES = {BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE,
BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR};
public static void main(String[] args) throws IOException {
/* Iterate over different image types */
for (int type : TYPES) {
BufferedImage testImg = getBufferedImage(type);
/* Draw anti-aliased string and check for artifacts */
drawAntialiasedString(testImg);
checkArtifact(testImg);
}
}
private static BufferedImage getBufferedImage(int imageType) {
/* Create a Graphics2D object from the given image type */
BufferedImage image = new BufferedImage(TEST_IMAGE_WIDTH,
TEST_IMAGE_HEIGHT,
imageType);
return image;
}
private static void drawAntialiasedString(BufferedImage image) {
/* Create Graphics2D object */
Graphics2D graphics = (Graphics2D) image.getGraphics();
/* Fill the image with translucent color */
graphics.setColor(new Color(127, 127, 127, 127));
graphics.fillRect(0, 0, TEST_IMAGE_WIDTH, TEST_IMAGE_HEIGHT);
/* Drawstring with Antialiasing hint */
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Font font = new Font("Verdana" , Font.PLAIN, 60);
graphics.setFont(font);
graphics.setColor(new Color(255, 0, 0));
graphics.drawString(TEST_STRING, 10, 75);
graphics.dispose();
}
private static void checkArtifact(BufferedImage image) throws IOException {
int componentMask = 0xff;
int colorThreshold = 200;
int rowIndex = 0;
int colIndex = 0;
/* Loop through every pixel to check for possible artifact */
for (rowIndex = 0; rowIndex < image.getHeight(); rowIndex++) {
for (colIndex = 0; colIndex < image.getWidth(); colIndex++) {
/*
* API: getRGB(x,y) returns color in INT_ARGB color space.
* Extract individual color components with a simple mask.
*/
int colorValue = image.getRGB(colIndex, rowIndex);
int colorComponent1 = colorValue & componentMask;
int colorComponent2 = (colorValue>>8) & componentMask;
int colorComponent3 = (colorValue>>16) & componentMask;
/*
* Artifacts are predominantly a subjective decision based on
* the quality of the rendered image content. However, in the
* current use-case, the artifacts around the edges of the anti
* aliased text appear like spots of white pixels without any
* relation to the color of foreground text or the background
* translucent shape.
*
* To identify the artifact pixels, each color component from
* the testImage is compared with a constant threshold. The
* component threshold has been set based on observation from
* different experiments on mulitple Java versions.
*/
if (colorComponent1 >= colorThreshold
&& colorComponent2 >= colorThreshold
&& colorComponent3 >= colorThreshold) {
/* Artifact has been noticed. Report error. */
throw new RuntimeException("Test Failed.");
}
}
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* @test
* @bug 7190349
* @summary Verifies that we get correct direction, when draw rotated string.
* @author Sergey Bylokhov
* @run main/othervm DrawRotatedString
*/
public final class DrawRotatedString {
private static final int SIZE = 500;
public static void main(final String[] args) throws IOException {
BufferedImage bi = createBufferedImage(true);
verify(bi);
bi = createBufferedImage(false);
verify(bi);
System.out.println("Passed");
}
private static void verify(BufferedImage bi) throws IOException {
for (int i = 0; i < SIZE; ++i) {
for (int j = 0; j < 99; ++j) {
//Text should not appear before 100
if (bi.getRGB(i, j) != Color.RED.getRGB()) {
ImageIO.write(bi, "png", new File("image.png"));
throw new RuntimeException("Failed: wrong text location");
}
}
}
}
private static BufferedImage createBufferedImage(final boolean aa) {
final BufferedImage bi = new BufferedImage(SIZE, SIZE,
BufferedImage.TYPE_INT_RGB);
final Graphics2D bg = bi.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
aa ? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF);
bg.setColor(Color.RED);
bg.fillRect(0, 0, SIZE, SIZE);
bg.translate(100, 100);
bg.rotate(Math.toRadians(90));
bg.setColor(Color.BLACK);
bg.setFont(bg.getFont().deriveFont(20.0f));
bg.drawString("MMMMMMMMMMMMMMMM", 0, 0);
bg.dispose();
return bi;
}
}

View file

@ -0,0 +1,163 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.lang.Math.toRadians;
/**
* @test
* @bug 8065373 8289208
* @key headful
* @summary Verifies that we get correct direction, when draw rotated string.
* @author Sergey Bylokhov
* @run main DrawRotatedStringUsingRotatedFont
*/
public final class DrawRotatedStringUsingRotatedFont {
private static final int SIZE = 500;
private static final String STR = "MMMMMMMMMMMMMMMM";
private static AffineTransform[] txs = {
AffineTransform.getRotateInstance(toRadians(00)),
AffineTransform.getRotateInstance(toRadians(45)),
AffineTransform.getRotateInstance(toRadians(-45)),
AffineTransform.getRotateInstance(toRadians(90)),
AffineTransform.getRotateInstance(toRadians(-90)),
AffineTransform.getRotateInstance(toRadians(135)),
AffineTransform.getRotateInstance(toRadians(-135)),
AffineTransform.getRotateInstance(toRadians(180)),
AffineTransform.getRotateInstance(toRadians(-180)),
AffineTransform.getRotateInstance(toRadians(225)),
AffineTransform.getRotateInstance(toRadians(-225)),
AffineTransform.getRotateInstance(toRadians(270)),
AffineTransform.getRotateInstance(toRadians(-270)),
AffineTransform.getRotateInstance(toRadians(315)),
AffineTransform.getRotateInstance(toRadians(-315)),
AffineTransform.getRotateInstance(toRadians(360)),
AffineTransform.getRotateInstance(toRadians(-360))
};
public static void main(final String[] args) throws IOException {
for (final AffineTransform tx2 : txs) {
for (final AffineTransform tx1 : txs) {
for (final boolean aa : new boolean[]{true, false}) {
final BufferedImage bi1 = createImage(aa, tx1, tx2);
final BufferedImage bi2 = createImage(aa, tx2, tx1);
compareImage(bi1, bi2);
fillTextArea(bi1, tx1, tx2);
fillTextArea(bi2, tx2, tx1);
checkColors(bi1, bi2);
}
}
}
System.out.println("Passed");
}
/**
* Compares two images.
*/
private static void compareImage(final BufferedImage bi1,
final BufferedImage bi2)
throws IOException {
for (int i = 0; i < SIZE; ++i) {
for (int j = 0; j < SIZE; ++j) {
if (bi1.getRGB(i, j) != bi2.getRGB(i, j)) {
ImageIO.write(bi1, "png", new File("image1.png"));
ImageIO.write(bi2, "png", new File("image2.png"));
throw new RuntimeException("Failed: wrong text location");
}
}
}
}
/**
* Checks an image color. RED and GREEN are allowed only.
*/
private static void checkColors(final BufferedImage bi1,
final BufferedImage bi2)
throws IOException {
for (int i = 0; i < SIZE; ++i) {
for (int j = 0; j < SIZE; ++j) {
final int rgb1 = bi1.getRGB(i, j);
final int rgb2 = bi2.getRGB(i, j);
if (rgb1 != rgb2 || rgb1 != 0xFFFF0000 && rgb1 != 0xFF00FF00) {
ImageIO.write(bi1, "png", new File("image1.png"));
ImageIO.write(bi2, "png", new File("image2.png"));
throw new RuntimeException("Failed: wrong text location");
}
}
}
}
/**
* Creates an BufferedImage and draws a text, using two transformations,
* one for graphics and one for font.
*/
private static BufferedImage createImage(final boolean aa,
final AffineTransform gtx,
final AffineTransform ftx) {
final BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB);
final Graphics2D bg = bi.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
aa ? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF);
bg.setColor(Color.RED);
bg.fillRect(0, 0, SIZE, SIZE);
bg.translate(100, 100);
bg.transform(gtx);
bg.setColor(Color.BLACK);
bg.setFont(bg.getFont().deriveFont(20.0f).deriveFont(ftx));
bg.drawString(STR, 0, 0);
bg.dispose();
return bi;
}
/**
* Fills the area of text using green solid color.
*/
private static void fillTextArea(final BufferedImage bi,
final AffineTransform tx1,
final AffineTransform tx2) {
final Graphics2D bg = bi.createGraphics();
bg.translate(100, 100);
bg.transform(tx1);
bg.transform(tx2);
bg.setColor(Color.GREEN);
final Font font = bg.getFont().deriveFont(20.0f);
bg.setFont(font);
bg.fill(font.getStringBounds(STR, bg.getFontRenderContext()));
bg.dispose();
}
}

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @key headful
* @bug 6684056
* @summary Super-scripted text needs to be positioned the same with
* drawString and TextLayout.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import static java.awt.font.TextAttribute.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.HashMap;
public class DrawStrSuper extends Component {
int angle = 0;
static boolean interactive = false;
int wid=400, hgt=400;
BufferedImage bi = null;
void paintImage() {
if (bi == null) {
bi = new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
}
Graphics2D g2d = bi.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, wid, hgt);
g2d.translate(200, 200);
Font fnt = new Font("Arial", Font.PLAIN, 20);
fnt = fnt.deriveFont(60.0f);
HashMap attrMap = new HashMap();
AffineTransform aff =
AffineTransform.getRotateInstance(angle * Math.PI/180.0);
attrMap.put(SUPERSCRIPT, SUPERSCRIPT_SUPER);
attrMap.put(TRANSFORM, aff);
fnt = fnt.deriveFont(attrMap);
g2d.setFont(fnt);
g2d.setColor(Color.yellow);
TextLayout tl = new TextLayout("Text", fnt,g2d.getFontRenderContext());
g2d.fill(tl.getBounds());
g2d.setColor(Color.black);
g2d.drawLine(-3, 0, 3, 0);
g2d.drawLine(0, -3, 0, 3);
g2d.setColor(Color.blue);
g2d.drawString("Text", 0, 0);
g2d.setColor(Color.red);
tl.draw(g2d,0f,0f);
// Test BI: should be no blue
int blue = Color.blue.getRGB();
for (int px=0;px<wid;px++) {
for (int py=0;py<hgt;py++) {
int rgb = bi.getRGB(px, py);
if (rgb == blue) {
throw new RuntimeException
("Unexpected color : " + Integer.toHexString(rgb) +
" at x=" + px + " y="+ py);
}
}
}
}
@Override
public void paint(Graphics g) {
paintImage();
g.drawImage(bi, 0,0, null);
}
static class Runner extends Thread {
DrawStrSuper dss;
Runner(DrawStrSuper dss) {
this.dss = dss;
}
public void run() {
while (true) {
if (!interactive && dss.angle > 360) {
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
dss.angle += 10;
dss.repaint();
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public static void main(String argv[]) throws InterruptedException {
if (argv.length > 0) interactive = true;
Frame f = new Frame("Text bounds test");
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
DrawStrSuper dss = new DrawStrSuper();
f.add(dss, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
Runner runner = new Runner(dss);
runner.start();
runner.join();
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8043508 8080084
* @summary Drawing a very long string crashes VM
* @run main/othervm DrawStringCrash
*/
import java.awt.*;
import java.awt.image.*;
public class DrawStringCrash {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
String s = "abcdefghijklmnopqrstuzwxyz";
for (int x = 0; x < 100000 ; x++) {
sb.append(s);
}
// Now have a string which uses approx 5Mb memory
// Loop again drawing doubling each time until
// we reach 8 billion chars or get OOME which means we can't
// go any further.
// Often there is no crash because Java OOM happens
// long before native heap runs out.
long maxLen = 8L * 1024 * 1024 * 1024;
int len = sb.length();
BufferedImage bi =
new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
while (len < maxLen) {
try {
g2d.drawString(sb.toString(), 20, 20);
sb.append(sb);
len *= 2;
} catch (OutOfMemoryError e) {
return;
}
}
return;
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6699843
* @summary IllegalArgumentException when using Graphics.drawString( "", 0, 0 )
*/
import java.awt.*;
import java.awt.font.*;
import java.awt.image.*;
import java.text.*;
import java.util.*;
public class EmptyAttrString {
public static void main(String[] args) {
BufferedImage bi =
new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
Font f = new Font( "Dialog", Font.PLAIN, 12 );
Map map = new HashMap();
map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
f = f.deriveFont(map);
g.setFont(f);
g.drawString("", 50, 50);
g.drawString("", 50f, 50f);
char[] chs = { } ;
g.drawChars(chs, 0, 0, 50, 50);
byte[] bytes = { } ;
g.drawBytes(bytes, 0, 0, 50, 50);
AttributedString astr = new AttributedString("");
g.drawString(astr.getIterator(), 50, 50);
g.drawString(astr.getIterator(), 50f, 50f);
return;
}
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8350203 8356966
* @summary Confirm that a few special whitespace characters are ignored.
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.text.AttributedString;
import java.util.Map;
public class IgnoredWhitespaceTest {
public static void main(String[] args) throws Exception {
BufferedImage image = new BufferedImage(600, 600, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = image.createGraphics();
Font font = new Font(Font.DIALOG, Font.PLAIN, 40);
test(image, g2d, font);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
test(image, g2d, font);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
test(image, g2d, font);
Font kerningFont = font.deriveFont(Map.of(TextAttribute.KERNING, TextAttribute.KERNING_ON));
test(image, g2d, kerningFont);
Font physicalFont = getPhysicalFont(40);
if (physicalFont != null) {
test(image, g2d, physicalFont);
}
g2d.dispose();
}
private static void test(BufferedImage image, Graphics2D g2d, Font font) {
test(image, g2d, font, "XXXXX", "\t\t\t\t\tXXXXX");
test(image, g2d, font, "XXXXX", "\tX\tX\tX\tX\tX\t");
test(image, g2d, font, "XXXXX", "\r\r\r\r\rXXXXX");
test(image, g2d, font, "XXXXX", "\rX\rX\rX\rX\rX\r");
test(image, g2d, font, "XXXXX", "\n\n\n\n\nXXXXX");
test(image, g2d, font, "XXXXX", "\nX\nX\nX\nX\nX\n");
}
private static void test(BufferedImage image, Graphics2D g2d, Font font, String reference, String text) {
g2d.setFont(font);
FontRenderContext frc = g2d.getFontRenderContext();
int w = image.getWidth();
int h = image.getHeight();
int x = w / 2;
int y = h / 2;
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
g2d.drawString(reference, x, y);
Rectangle expected = findTextBoundingBox(image);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
g2d.drawString(text, x, y);
Rectangle actual = findTextBoundingBox(image);
assertEqual(expected, actual, text, font);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
g2d.drawString(new AttributedString(text, Map.of(TextAttribute.FONT, font)).getIterator(), x, y);
actual = findTextBoundingBox(image);
assertEqual(expected, actual, text, font);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
g2d.drawChars(text.toCharArray(), 0, text.length(), x, y);
actual = findTextBoundingBox(image);
assertEqual(expected, actual, text, font);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
g2d.drawGlyphVector(font.createGlyphVector(frc, text), x, y);
actual = findTextBoundingBox(image);
assertEqual(expected, actual, text, font);
}
private static void assertEqual(Rectangle r1, Rectangle r2, String text, Font font) {
if (!r1.equals(r2)) {
String escaped = text.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t");
String msg = String.format("for text '%s' with font %s: %s != %s",
escaped, font.toString(), r1.toString(), r2.toString());
throw new RuntimeException(msg);
}
}
private static Font getPhysicalFont(int size) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] names = ge.getAvailableFontFamilyNames();
for (String n : names) {
switch (n) {
case Font.DIALOG:
case Font.DIALOG_INPUT:
case Font.SERIF:
case Font.SANS_SERIF:
case Font.MONOSPACED:
continue;
default:
Font f = new Font(n, Font.PLAIN, size);
if (f.canDisplayUpTo("AZaz09") == -1) {
return f;
}
}
}
return null;
}
private static Rectangle findTextBoundingBox(BufferedImage image) {
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
int width = image.getWidth();
int height = image.getHeight();
int[] rowPixels = new int[width];
for (int y = 0; y < height; y++) {
image.getRGB(0, y, width, 1, rowPixels, 0, width);
for (int x = 0; x < width; x++) {
boolean white = (rowPixels[x] == -1);
if (!white) {
if (x < minX) {
minX = x;
}
if (y < minY) {
minY = y;
}
if (x > maxX) {
maxX = x;
}
if (y > maxY) {
maxY = y;
}
}
}
}
if (minX != Integer.MAX_VALUE) {
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
} else {
return null;
}
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6996867 8223543
* @requires (os.family == "windows")
* @summary Render as LCD Text in SrcEa composite mode.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
public class LCDTextSrcEa {
public static void main(String[] args) {
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("mac")) {
System.out.println("macOS doesn't support LCD any more. Skipping");
return;
}
/* Sometimes freetype on Linux is built without LCD support, so
* it can't be relied upon to test there.
*/
if (os.toLowerCase().startsWith("linux")) {
System.out.println("Linux freetype may not do LCD. Skipping");
return;
}
int SZ=200;
BufferedImage target =
new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) target.getGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, SZ, SZ);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.01f));
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
g2d.drawString("Some sample text.", 10, 20);
boolean nongrey = false;
//Test BI: should be some non-greyscale color
for (int px=0;px<SZ;px++) {
for (int py=0;py<SZ;py++) {
int rgb = target.getRGB(px, py);
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0x00ff00) >> 8;
int b = (rgb & 0x0000ff);
if (r != g || r !=b || g != b) {
nongrey=true;
break;
}
}
}
if (!nongrey) {
throw new RuntimeException("No LCD text found");
}
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6683472 6687298 8197797
* @summary Transformed fonts using drawString and TextLayout should be in
* the same position.
*/
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.HashMap;
public class RotTransText {
public static void main(String[] args) {
testIt(false);
testIt(true);
}
public static void testIt(boolean fmOn) {
int wid=400, hgt=400;
BufferedImage bi =
new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
if (fmOn) {
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
}
int x=130, y=130;
String s = "Text";
int xt=90, yt=50;
for (int angle=0;angle<360;angle+=30) {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, wid, hgt);
AffineTransform aff = AffineTransform.getTranslateInstance(50,90);
aff.rotate(angle * Math.PI/180.0);
Font fnt = new Font("SansSerif", Font.PLAIN, 60);
fnt = fnt.deriveFont(Font.PLAIN, aff);
g2d.setFont(fnt);
g2d.setColor(Color.blue);
g2d.drawString(s, x, y);
g2d.setColor(Color.red);
FontRenderContext frc = g2d.getFontRenderContext();
HashMap attrMap = new HashMap();
attrMap.put(TextAttribute.STRIKETHROUGH,
TextAttribute.STRIKETHROUGH_ON);
fnt = fnt.deriveFont(attrMap);
TextLayout tl = new TextLayout(s, fnt, frc);
tl.draw(g2d, (float)x, (float)y);
// Test BI: should be minimal blue relative to red.
int redCount = 0;
int blueCount = 0;
int red = Color.red.getRGB();
int blue = Color.blue.getRGB();
for (int px=0;px<wid;px++) {
for (int py=0;py<hgt;py++) {
int rgb = bi.getRGB(px, py);
if (rgb == red) {
redCount++;
} else if (rgb == blue) {
blueCount++;
}
}
}
if (redCount == 0 || (blueCount/(double)redCount) > 0.1) {
throw new
RuntimeException("Ratio of blue to red is too great: " +
(blueCount/(double)redCount));
}
}
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @key headful
* @bug 6685312
* @summary Check advance of LCD text on a scaled graphics.
*/
import javax.swing.*;
import java.awt.*;
import static java.awt.RenderingHints.*;
public class ScaledLCDTextMetrics extends Component {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add("Center", new ScaledLCDTextMetrics());
f.pack();
f.setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(200,100);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
Font f = new Font("Tahoma", Font.PLAIN, 11);
g.setFont(f);
g.setColor(Color.white);
g.fillRect(0,0,400,300);
g.setColor(Color.black);
g2.setRenderingHint(KEY_TEXT_ANTIALIASING,VALUE_TEXT_ANTIALIAS_LCD_HRGB);
String text = "ABCDEFGHIJKLI";
FontMetrics fm1 = g2.getFontMetrics();
int adv1 = fm1.stringWidth(text);
g.drawString(text, 5, 20);
g2.scale(2,2);
FontMetrics fm2 = g2.getFontMetrics();
int adv2 = fm2.stringWidth(text);
g.drawString(text, 5, 40);
double frac = Math.abs(adv1/(double)adv2);
System.out.println("scalex1: " + adv1);
System.out.println("scalex2: " + adv2);
System.out.println("Fraction : "+ frac);
// adv1 will not be exactly the same as adv2, but should differ
// only by a fraction.
if (frac < 0.8 || frac > 1.2) {
throw new RuntimeException("Metrics differ " +
"Adv1="+adv1+" Adv2="+adv2+" Fraction="+frac);
}
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GradientPaint;
import java.awt.geom.Point2D;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
/*
* @test
* @key headful
* @bug 7189452 8024767
* @summary Check if source offset for text rendering is handled correctly
* (shouldn't see the text on a similarly colored background).
* @author a.stepanov
* @run main TextRenderingTest
*/
public class TextRenderingTest {
private static final int width = 450;
private static final int height = 150;
public static void main(final String[] args) {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc =
ge.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(width, height);
while (true) {
vi.validate(gc);
Graphics2D g2d = vi.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(new GradientPaint(
new Point2D.Float(0, height / 2), Color.white,
new Point2D.Float(width, height / 2), Color.black));
g2d.fillRect(0, 0, width, height);
String fnt = g2d.getFont().getFamily();
g2d.setFont(new Font(fnt, Font.PLAIN, 100));
g2d.drawString("IIIIIIIIII", 100, 100); // draw text with offset
g2d.dispose();
if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
continue;
}
if (vi.contentsLost()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
continue;
}
break;
}
BufferedImage bi = vi.getSnapshot();
// the text shifted shouldn't be visible onto a painted rectangle!
// so the check: color component (blue) must decrease monotonously
int prev = Integer.MAX_VALUE;
for (int x = 0; x < width; ++x) {
int color = bi.getRGB(x, height / 2);
int b = color & 0xFF;
if (b > prev) {
throw new RuntimeException("test failed: can see the text rendered!");
}
prev = b;
}
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.MultipleGradientPaint.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
/**
* @test
* @key headful
* @bug 8028722
* @summary tests whether drawString with 254 characters causes the xrender
* pipeline to hang.
* @author ceisserer
*/
public class XRenderElt254TextTest extends Frame implements Runnable {
public volatile boolean success = false;
public void run() {
Image dstImg = getGraphicsConfiguration().createCompatibleVolatileImage(400, 400);
Graphics2D g = (Graphics2D) dstImg.getGraphics();
StringBuilder strBuilder = new StringBuilder(254);
for (int c = 0; c < 254; c++) {
strBuilder.append('a');
}
for (int i = 0; i < 100; i++) {
g.drawString(strBuilder.toString(), 20, 20);
Toolkit.getDefaultToolkit().sync();
}
success = true;
}
public static void main(String[] args) throws Exception {
XRenderElt254TextTest test = new XRenderElt254TextTest();
new Thread(test).start();
for (int i = 0; i < 30; i++) {
Thread.sleep(1000);
if (test.success) {
return; // Test finished successful
}
}
throw new RuntimeException("Test Failed");
}
}