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:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
475
test/jdk/java/awt/geom/EqualsHashcode.java
Normal file
475
test/jdk/java/awt/geom/EqualsHashcode.java
Normal file
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2018, 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 6210287
|
||||
* @summary Verifies that the various utility shapes implement
|
||||
* the equals(Object) and hashCode methods adequately
|
||||
*/
|
||||
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.Vector;
|
||||
|
||||
public class EqualsHashcode {
|
||||
public static final int NUMTESTS = 1000;
|
||||
|
||||
public static void main(String argv[]) {
|
||||
new FloatRectangleTester().test();
|
||||
new DoubleRectangleTester().test();
|
||||
|
||||
new FloatEllipseTester().test();
|
||||
new DoubleEllipseTester().test();
|
||||
|
||||
new FloatArcTester().test();
|
||||
new DoubleArcTester().test();
|
||||
|
||||
new FloatRoundRectTester().test();
|
||||
new DoubleRoundRectTester().test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Base utility class for random parameters for testing
|
||||
*/
|
||||
public static abstract class Val {
|
||||
protected String name;
|
||||
|
||||
protected Val(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract Object save();
|
||||
public abstract void restore(Object save);
|
||||
|
||||
public abstract void randomize();
|
||||
public abstract void perturb();
|
||||
}
|
||||
|
||||
/**
|
||||
* Base subclass for parameters with "special" values (Infinity, NaN, etc.)
|
||||
*/
|
||||
public static abstract class SpecialVal extends Val {
|
||||
protected SpecialVal(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public abstract void setSpecial();
|
||||
|
||||
public abstract boolean isNaN();
|
||||
}
|
||||
|
||||
/**
|
||||
* Floating point parameter
|
||||
*/
|
||||
public static class FloatVal extends SpecialVal {
|
||||
private float v;
|
||||
|
||||
public FloatVal(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public float getVal() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name+" = "+v+" (flt)";
|
||||
}
|
||||
|
||||
public Object save() {
|
||||
return new Float(v);
|
||||
}
|
||||
|
||||
public void restore(Object o) {
|
||||
v = ((Float) o).floatValue();
|
||||
}
|
||||
|
||||
public void randomize() {
|
||||
v = (float) (Math.random() * 100);
|
||||
}
|
||||
|
||||
public void perturb() {
|
||||
v = v + 1;
|
||||
}
|
||||
|
||||
public boolean hasSpecialCases() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSpecial() {
|
||||
switch ((int) (Math.random() * 3)) {
|
||||
case 0:
|
||||
v = Float.NaN;
|
||||
break;
|
||||
case 1:
|
||||
v = Float.POSITIVE_INFINITY;
|
||||
break;
|
||||
case 2:
|
||||
v = Float.NEGATIVE_INFINITY;
|
||||
break;
|
||||
default:
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNaN() {
|
||||
return (v != v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Double precision parameter
|
||||
*/
|
||||
public static class DoubleVal extends SpecialVal {
|
||||
private double v;
|
||||
|
||||
public DoubleVal(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public double getVal() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name+" = "+v+" (dbl)";
|
||||
}
|
||||
|
||||
public Object save() {
|
||||
return new Double(v);
|
||||
}
|
||||
|
||||
public void restore(Object o) {
|
||||
v = ((Double) o).doubleValue();
|
||||
}
|
||||
|
||||
public void randomize() {
|
||||
v = Math.random() * 100;
|
||||
}
|
||||
|
||||
public void perturb() {
|
||||
v = v + 1;
|
||||
}
|
||||
|
||||
public boolean hasSpecialCases() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSpecial() {
|
||||
switch ((int) (Math.random() * 3)) {
|
||||
case 0:
|
||||
v = Double.NaN;
|
||||
break;
|
||||
case 1:
|
||||
v = Double.POSITIVE_INFINITY;
|
||||
break;
|
||||
case 2:
|
||||
v = Double.NEGATIVE_INFINITY;
|
||||
break;
|
||||
default:
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNaN() {
|
||||
return (v != v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer value with a specified min/max range.
|
||||
*/
|
||||
public static class IntRangeVal extends Val {
|
||||
public int v;
|
||||
public int min;
|
||||
public int max;
|
||||
|
||||
public IntRangeVal(String name, int min, int max) {
|
||||
super(name);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int getVal() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name+" = "+v;
|
||||
}
|
||||
|
||||
public Object save() {
|
||||
return new Integer(v);
|
||||
}
|
||||
|
||||
public void restore(Object o) {
|
||||
v = ((Integer) o).intValue();
|
||||
}
|
||||
|
||||
public void randomize() {
|
||||
v = min + (int) (Math.random() * (max-min+1));
|
||||
}
|
||||
|
||||
public void perturb() {
|
||||
v = v + 1;
|
||||
if (v > max) {
|
||||
v = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for testing a given type of shape.
|
||||
* Subclasses must register all of their "parameters" which
|
||||
* need to be randomized, specialized, and perturbed for
|
||||
* testing.
|
||||
* Subclasses must also implement makeShape() which makes
|
||||
* a new shape object according to the current values of
|
||||
* all of their parameters.
|
||||
*/
|
||||
public static abstract class ShapeTester {
|
||||
public Vector params = new Vector();
|
||||
|
||||
public void addParam(Val v) {
|
||||
params.add(v);
|
||||
}
|
||||
|
||||
public Val[] getParamArray() {
|
||||
Val ret[] = new Val[params.size()];
|
||||
for (int i = 0; i < params.size(); i++) {
|
||||
ret[i] = (Val) params.get(i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void error(String desc) {
|
||||
Val params[] = getParamArray();
|
||||
for (int j = 0; j < params.length; j++) {
|
||||
System.err.println(params[j]);
|
||||
}
|
||||
throw new RuntimeException(desc);
|
||||
}
|
||||
|
||||
public abstract Object makeShape();
|
||||
|
||||
public void test() {
|
||||
Val params[] = getParamArray();
|
||||
for (int i = 0; i < NUMTESTS; i++) {
|
||||
// First, randomize all parameters
|
||||
for (int j = 0; j < params.length; j++) {
|
||||
params[j].randomize();
|
||||
}
|
||||
|
||||
// Now make 2 copies from the same params and verify equals()
|
||||
Object o1 = makeShape();
|
||||
if (!o1.equals(o1)) {
|
||||
error("Shapes not equal to itself!");
|
||||
}
|
||||
Object o2 = makeShape();
|
||||
if (!o1.equals(o2)) {
|
||||
error("Identical shapes not equal!");
|
||||
}
|
||||
if (o1.hashCode() != o2.hashCode()) {
|
||||
error("Identical hashes not equal!");
|
||||
}
|
||||
|
||||
// Now perturb the params 1 by 1 and verify !equals()
|
||||
for (int j = 0; j < params.length; j++) {
|
||||
Val param = params[j];
|
||||
Object save = param.save();
|
||||
|
||||
param.perturb();
|
||||
Object o3 = makeShape();
|
||||
if (o1.equals(o3)) {
|
||||
error("Perturbed shape still equal!");
|
||||
}
|
||||
|
||||
// If param has "special values", test them as well
|
||||
if (param instanceof SpecialVal) {
|
||||
SpecialVal sparam = (SpecialVal) param;
|
||||
sparam.setSpecial();
|
||||
Object o4 = makeShape();
|
||||
if (o1.equals(o4)) {
|
||||
error("Specialized shape still equal!");
|
||||
}
|
||||
Object o5 = makeShape();
|
||||
// objects equal iff param is not a NaN
|
||||
if (o4.equals(o5) == sparam.isNaN()) {
|
||||
error("Identical specialized shapes not equal!");
|
||||
}
|
||||
// hash codes always equal, even if NaN
|
||||
// (Note: equals()/hashCode() contract allows this)
|
||||
if (o4.hashCode() != o5.hashCode()) {
|
||||
error("Identical specialized hashes not equal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Restore original value of param and make sure
|
||||
param.restore(save);
|
||||
Object o6 = makeShape();
|
||||
if (!o1.equals(o6)) {
|
||||
error("Restored shape not equal!");
|
||||
}
|
||||
if (o1.hashCode() != o6.hashCode()) {
|
||||
error("Restored hash not equal!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base tester class for objects with floating point xywh bounds
|
||||
*/
|
||||
public static abstract class FloatBoundedShape extends ShapeTester {
|
||||
public FloatVal x = new FloatVal("x");
|
||||
public FloatVal y = new FloatVal("y");
|
||||
public FloatVal w = new FloatVal("w");
|
||||
public FloatVal h = new FloatVal("h");
|
||||
|
||||
public FloatBoundedShape() {
|
||||
addParam(x);
|
||||
addParam(y);
|
||||
addParam(w);
|
||||
addParam(h);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base tester class for objects with double precision xywh bounds
|
||||
*/
|
||||
public static abstract class DoubleBoundedShape extends ShapeTester {
|
||||
public DoubleVal x = new DoubleVal("x");
|
||||
public DoubleVal y = new DoubleVal("y");
|
||||
public DoubleVal w = new DoubleVal("w");
|
||||
public DoubleVal h = new DoubleVal("h");
|
||||
|
||||
public DoubleBoundedShape() {
|
||||
addParam(x);
|
||||
addParam(y);
|
||||
addParam(w);
|
||||
addParam(h);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatRectangleTester extends FloatBoundedShape {
|
||||
public Object makeShape() {
|
||||
return new Rectangle2D.Float(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleRectangleTester extends DoubleBoundedShape {
|
||||
public Object makeShape() {
|
||||
return new Rectangle2D.Double(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatEllipseTester extends FloatBoundedShape {
|
||||
public Object makeShape() {
|
||||
return new Ellipse2D.Float(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleEllipseTester extends DoubleBoundedShape {
|
||||
public Object makeShape() {
|
||||
return new Ellipse2D.Double(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatArcTester extends FloatBoundedShape {
|
||||
public FloatVal start = new FloatVal("start");
|
||||
public FloatVal extent = new FloatVal("extent");
|
||||
public IntRangeVal type = new IntRangeVal("type", 0, 2);
|
||||
|
||||
public FloatArcTester() {
|
||||
addParam(start);
|
||||
addParam(extent);
|
||||
addParam(type);
|
||||
}
|
||||
|
||||
public Object makeShape() {
|
||||
return new Arc2D.Float(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal(),
|
||||
start.getVal(), extent.getVal(),
|
||||
type.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleArcTester extends DoubleBoundedShape {
|
||||
public DoubleVal start = new DoubleVal("start");
|
||||
public DoubleVal extent = new DoubleVal("extent");
|
||||
public IntRangeVal type = new IntRangeVal("type", 0, 2);
|
||||
|
||||
public DoubleArcTester() {
|
||||
addParam(start);
|
||||
addParam(extent);
|
||||
addParam(type);
|
||||
}
|
||||
|
||||
public Object makeShape() {
|
||||
return new Arc2D.Double(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal(),
|
||||
start.getVal(), extent.getVal(),
|
||||
type.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatRoundRectTester extends FloatBoundedShape {
|
||||
public FloatVal arcw = new FloatVal("arcw");
|
||||
public FloatVal arch = new FloatVal("arch");
|
||||
|
||||
public FloatRoundRectTester() {
|
||||
addParam(arcw);
|
||||
addParam(arch);
|
||||
}
|
||||
|
||||
public Object makeShape() {
|
||||
return new RoundRectangle2D.Float(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal(),
|
||||
arcw.getVal(), arch.getVal());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleRoundRectTester extends DoubleBoundedShape {
|
||||
public DoubleVal arcw = new DoubleVal("arcw");
|
||||
public DoubleVal arch = new DoubleVal("arch");
|
||||
|
||||
public DoubleRoundRectTester() {
|
||||
addParam(arcw);
|
||||
addParam(arch);
|
||||
}
|
||||
|
||||
public Object makeShape() {
|
||||
return new RoundRectangle2D.Double(x.getVal(), y.getVal(),
|
||||
w.getVal(), h.getVal(),
|
||||
arcw.getVal(), arch.getVal());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue