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
437
test/jdk/com/sun/jdi/VarargsTest.java
Normal file
437
test/jdk/com/sun/jdi/VarargsTest.java
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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 4870984
|
||||
* @summary JPDA: Add support for RFE 4856541 - varargs
|
||||
* @author jjh
|
||||
*
|
||||
* @run build TestScaffold VMConnection TargetListener TargetAdapter
|
||||
* @run compile -g VarargsTest.java
|
||||
* @run driver VarargsTest
|
||||
*/
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/********** target program **********/
|
||||
|
||||
class VarargsTarg {
|
||||
|
||||
// These are args that will get passed
|
||||
static String[] strArray = new String[] {"a", "b"};
|
||||
static int[] intArray = new int[] {1, 2};
|
||||
|
||||
// We will pass these to a varargs instance method
|
||||
static VarargsTarg vt1 = new VarargsTarg("vt1", "");
|
||||
static VarargsTarg vt2 = new VarargsTarg("vt2", "");
|
||||
|
||||
String iname;
|
||||
|
||||
VarargsTarg(String ... name) {
|
||||
iname = "";
|
||||
for (int ii = 0; ii < name.length; ii++) {
|
||||
iname += name[ii];
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
System.out.println("Howdy!");
|
||||
/*
|
||||
* This isn't really part of the test, it just shows
|
||||
* the kinds of calls the debugger test will do and lets
|
||||
* you verify how javac handles these calls.
|
||||
*/
|
||||
System.out.println("debuggee: " + varString());
|
||||
System.out.println("debuggee: " + varString(null));
|
||||
System.out.println("debuggee: " + varString("a"));
|
||||
System.out.println("debuggee: " + varString("b", "c"));
|
||||
System.out.println("debuggee: " + fixedString(null));
|
||||
System.out.println("debuggee: " + vt1.varStringInstance(vt1, vt2));
|
||||
System.out.println("debuggge: " + varInt(1, 2, 3));
|
||||
System.out.println("debuggee: " + varInteger( new Integer(89)));
|
||||
|
||||
// Should be autoboxed: javac converts the ints to Integers
|
||||
// Needs a new method in java.lang.Integer which is only
|
||||
// in the generics workspace.
|
||||
System.out.println("debugggee: " + varInteger(3, 5, 6));
|
||||
|
||||
System.out.println("Goodbye from VarargsTarg!");
|
||||
bkpt();
|
||||
}
|
||||
static void bkpt() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the methods to be called from the debugger
|
||||
*/
|
||||
static String fixedInt(int p1) {
|
||||
return "" + p1;
|
||||
}
|
||||
|
||||
static String fixedInteger(Integer p1) {
|
||||
return "" + p1;
|
||||
}
|
||||
|
||||
static String varInt(int... ss) {
|
||||
String retVal = "";
|
||||
for (int ii = 0; ii < ss.length; ii++) {
|
||||
retVal += ss[ii];
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static String varInteger(Integer... ss) {
|
||||
String retVal = "";
|
||||
for (int ii = 0; ii < ss.length; ii++) {
|
||||
retVal += ss[ii];
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static String varString(String... ss) {
|
||||
if (ss == null) {
|
||||
return "-null-";
|
||||
}
|
||||
|
||||
String retVal = "";
|
||||
for (int ii = 0; ii < ss.length; ii++) {
|
||||
retVal += ss[ii];
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static String varString2(int p1, String... ss) {
|
||||
return p1 + varString(ss);
|
||||
}
|
||||
|
||||
static String fixedString(String ss) {
|
||||
return "-fixed-";
|
||||
}
|
||||
|
||||
String varStringInstance(VarargsTarg... args) {
|
||||
if (args == null) {
|
||||
return "-null-";
|
||||
}
|
||||
//System.out.println("debugee: ss length = " + ss.length);
|
||||
String retVal = iname + ": ";
|
||||
for (int ii = 0; ii < args.length; ii++) {
|
||||
retVal += args[ii].iname;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********** test program **********/
|
||||
|
||||
public class VarargsTest extends TestScaffold {
|
||||
ClassType targetClass;
|
||||
ThreadReference mainThread;
|
||||
|
||||
VarargsTest (String args[]) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new VarargsTest(args).startTests();
|
||||
}
|
||||
|
||||
void fail(String reason) {
|
||||
failure(reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call a method in the debuggee and verify the return value.
|
||||
*/
|
||||
void doInvoke(Object ct, Method mm, List args, Object expected) {
|
||||
StringReference returnValue = null;
|
||||
try {
|
||||
returnValue = doInvokeNoVerify(ct, mm, args);
|
||||
} catch (Exception ee) {
|
||||
fail("failure: invokeMethod got exception : " + ee);
|
||||
ee.printStackTrace();
|
||||
return;
|
||||
}
|
||||
if (!returnValue.value().equals(expected)) {
|
||||
fail("failure: expected \"" + expected + "\", got \"" +
|
||||
returnValue.value() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call a method in the debuggee.
|
||||
*/
|
||||
StringReference doInvokeNoVerify(Object ct, Method mm, List args)
|
||||
throws Exception {
|
||||
StringReference returnValue = null;
|
||||
if (ct instanceof ClassType) {
|
||||
returnValue = (StringReference)((ClassType)ct).
|
||||
invokeMethod(mainThread, mm, args, 0);
|
||||
} else {
|
||||
returnValue = (StringReference)((ObjectReference)ct).
|
||||
invokeMethod(mainThread, mm, args, 0);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/********** test core **********/
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
/*
|
||||
* Get to the top of main()
|
||||
* to determine targetClass and mainThread
|
||||
*/
|
||||
BreakpointEvent bpe = startToMain("VarargsTarg");
|
||||
targetClass = (ClassType)bpe.location().declaringType();
|
||||
mainThread = bpe.thread();
|
||||
|
||||
/*
|
||||
* Run past the calls the debuggee makes
|
||||
* just to see what they do.
|
||||
*/
|
||||
bpe = resumeTo("VarargsTarg", "bkpt", "()V");
|
||||
|
||||
/*
|
||||
* Find Method objects for varString and varString2
|
||||
* Both are tested just to show that the code works
|
||||
* if there is just one param or if there is more than one.
|
||||
*/
|
||||
ReferenceType rt = findReferenceType("VarargsTarg");
|
||||
|
||||
List mList;
|
||||
|
||||
/*
|
||||
* The test consists of calling the varargs static and instance methods
|
||||
* (and constructor) passing primitives, Strings, and Objects, and also
|
||||
* passing arrays of the above instead of individual args.
|
||||
* The same code is used in the underlying JDI implementations
|
||||
* for calling instance methods, static methods, and constructors
|
||||
* so this test doesn't have to try all possible argument configurations
|
||||
* with each type of method.
|
||||
*/
|
||||
|
||||
mList = rt.methodsByName("varString");
|
||||
Method varString = (Method)mList.get(0);
|
||||
|
||||
mList = rt.methodsByName("varString2");
|
||||
Method varString2 = (Method)mList.get(0);
|
||||
|
||||
if (!varString.isVarArgs()) {
|
||||
fail("failure: varString is not flagged as being var args");
|
||||
}
|
||||
if (!varString2.isVarArgs()) {
|
||||
fail("failure: varString2 is not flagged as being var args");
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup arg lists for both varString and varString2 that
|
||||
* have null in the varargs position.
|
||||
*/
|
||||
|
||||
{
|
||||
// call varString()
|
||||
ArrayList nullArg1 = new ArrayList(0);
|
||||
doInvoke(targetClass, varString, nullArg1, "");
|
||||
}
|
||||
{
|
||||
// call varString(null)
|
||||
ArrayList nullArg1 = new ArrayList(1);
|
||||
nullArg1.add(null);
|
||||
doInvoke(targetClass, varString, nullArg1, "-null-");
|
||||
}
|
||||
{
|
||||
// call varString(9)
|
||||
ArrayList nullArg2 = new ArrayList(1);
|
||||
nullArg2.add(vm().mirrorOf(9));
|
||||
doInvoke(targetClass, varString2, nullArg2, "9");
|
||||
}
|
||||
{
|
||||
// call varString(9, null)
|
||||
ArrayList nullArg2 = new ArrayList(2);
|
||||
nullArg2.add(vm().mirrorOf(9));
|
||||
nullArg2.add(null);
|
||||
doInvoke(targetClass, varString2, nullArg2, "9-null-");
|
||||
}
|
||||
{
|
||||
ArrayList args1 = new ArrayList(4);
|
||||
args1.add(vm().mirrorOf("1"));
|
||||
|
||||
// call varString("1")
|
||||
doInvoke(targetClass, varString, args1, "1");
|
||||
|
||||
// call varString("1", "2")
|
||||
args1.add(vm().mirrorOf("2"));
|
||||
args1.add(vm().mirrorOf("3"));
|
||||
args1.add(vm().mirrorOf("4"));
|
||||
doInvoke(targetClass, varString, args1, "1234");
|
||||
}
|
||||
{
|
||||
ArrayList args2 = new ArrayList(2);
|
||||
args2.add(vm().mirrorOf(9));
|
||||
args2.add(vm().mirrorOf("1"));
|
||||
|
||||
// call varString2(9, "1");
|
||||
doInvoke(targetClass, varString2, args2, "91");
|
||||
|
||||
// call varString2(9, "1", "2");
|
||||
args2.add(vm().mirrorOf("2"));
|
||||
doInvoke(targetClass, varString2, args2, "912");
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* Passing an array of Strings should work too.
|
||||
*/
|
||||
Field ff = targetClass.fieldByName("strArray");
|
||||
Value vv1 = targetClass.getValue(ff);
|
||||
|
||||
// call varString(new String[] {"a", "b"})
|
||||
ArrayList argsArray = new ArrayList(1);
|
||||
argsArray.add(vv1);
|
||||
doInvoke(targetClass, varString, argsArray, "ab");
|
||||
|
||||
/*
|
||||
* But passing an array of Strings and another String
|
||||
* should fail
|
||||
*/
|
||||
argsArray.add(vm().mirrorOf("x"));
|
||||
boolean isOk = false;
|
||||
try {
|
||||
// call varString(new String[] {"a", "b"}, "x")
|
||||
doInvokeNoVerify(targetClass, varString, argsArray);
|
||||
} catch (Exception ee) {
|
||||
/*
|
||||
* Since the number of args passed is > than
|
||||
* the number of params, JDI assumes they are var args
|
||||
* and tries to put the array containing the "a" and
|
||||
* "b" elements into the first element of an array
|
||||
* of Strings. This fails because you can't store
|
||||
* an array into a String
|
||||
*/
|
||||
isOk = true;
|
||||
//ee.printStackTrace();
|
||||
}
|
||||
if (!isOk) {
|
||||
fail("failure: an array and a String didn't cause an exception");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* Test calling instance method instead of static method,
|
||||
* and passing non-String objects
|
||||
*/
|
||||
Field vtField = targetClass.fieldByName("vt1");
|
||||
Value vv1 = targetClass.getValue(vtField);
|
||||
|
||||
vtField = targetClass.fieldByName("vt2");
|
||||
Value vv2 = targetClass.getValue(vtField);
|
||||
|
||||
/* Create a new instance by calling the varargs
|
||||
* ctor.
|
||||
* call new VarargsTarg("vt3", "xx");
|
||||
*/
|
||||
Value vv3;
|
||||
{
|
||||
mList = rt.methodsByName("<init>");
|
||||
Method ctor = (Method)mList.get(0);
|
||||
if (!ctor.isVarArgs()) {
|
||||
fail("failure: Constructor is not varargs");
|
||||
}
|
||||
ArrayList argsArray = new ArrayList(2);
|
||||
argsArray.add(vm().mirrorOf("vt3"));
|
||||
argsArray.add(vm().mirrorOf("xx"));
|
||||
vv3 = targetClass.newInstance(mainThread, ctor, argsArray, 0);
|
||||
}
|
||||
// call vt1.varStringInstance(vv1, vv2, vv3)
|
||||
mList = rt.methodsByName("varStringInstance");
|
||||
Method varStringInstance = (Method)mList.get(0);
|
||||
|
||||
ArrayList argsArray = new ArrayList(3);
|
||||
argsArray.add(vv1);
|
||||
argsArray.add(vv2);
|
||||
argsArray.add(vv3);
|
||||
doInvoke(vv1, varStringInstance, argsArray, "vt1: vt1vt2vt3xx");
|
||||
}
|
||||
{
|
||||
/*
|
||||
* tests with primitive types
|
||||
*/
|
||||
List mlist;
|
||||
Method mm;
|
||||
ArrayList ll = new ArrayList(2);
|
||||
|
||||
// call fixedInt(21)
|
||||
mlist = rt.methodsByName("fixedInt");
|
||||
mm = (Method)mlist.get(0);
|
||||
ll.add(vm().mirrorOf(21));
|
||||
doInvoke(targetClass, mm, ll, "21");
|
||||
|
||||
// autoboxing is not implemented in JDI.
|
||||
// call fixedInteger(21)
|
||||
//mlist = rt.methodsByName("fixedInteger");
|
||||
//mm = (Method)mlist.get(0);
|
||||
//doInvoke(targetClass, mm, ll, "21");
|
||||
|
||||
mlist = rt.methodsByName("varInt");
|
||||
mm = (Method)mlist.get(0);
|
||||
|
||||
// call varInt( new int[] {1, 2});
|
||||
Field ff = targetClass.fieldByName("intArray");
|
||||
Value vv1 = targetClass.getValue(ff);
|
||||
ll.set(0, vv1);
|
||||
doInvoke(targetClass, mm, ll, "12");
|
||||
|
||||
// call varInt(21, 22)
|
||||
ll.set(0, vm().mirrorOf(21));
|
||||
ll.add(vm().mirrorOf(22));
|
||||
doInvoke(targetClass, mm, ll, "2122");
|
||||
|
||||
mlist = rt.methodsByName("varInteger");
|
||||
mm = (Method)mlist.get(0);
|
||||
|
||||
// call varInteger(1, 2)
|
||||
// autoboxing is not implemented.
|
||||
//doInvoke(targetClass, mm, ll, "2122");
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't really need this for the test, but
|
||||
* but without it, we sometimes hit 4728096.
|
||||
*/
|
||||
listenUntilVMDisconnect();
|
||||
/*
|
||||
* deal with results of test
|
||||
* if anything has called failure("foo") testFailed will be true
|
||||
*/
|
||||
if (!testFailed) {
|
||||
println("VarargsTest: passed");
|
||||
} else {
|
||||
throw new Exception("VarargsTest: failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue