Initial contribution of core script analysis code

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@624 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2007-02-02 17:28:04 +00:00
parent 54afed2310
commit 50fd961772
29 changed files with 6064 additions and 0 deletions

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="harness-src"/>
<classpathentry kind="src" path="examples-src"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1 @@
bin

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.ibm.wala.cast.js.test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,4 @@
source.test.jar = harness-src/
output.test.jar = bin/
bin.includes = plugin.xml,\
test.jar

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
=======================================================================
DOMO JavaScript Tests build file
=======================================================================
-->
<project name="com.ibm.domo.js.test" default="build-everything" basedir=".">
<!-- Software version details -->
<property name="name" value="domojstests" />
<property name="module_name" value="com.ibm.domo.js.test" />
<property name="Name" value="DOMO JS tests" />
<property name="version" value="1-alpha" />
<!-- Compilation switches -->
<property name="debug" value="true" />
<property name="deprecation" value="false" />
<property name="optimize" value="true" />
<property name="javacFailOnError" value="true" />
<property name="javacDebugInfo" value="on" />
<property name="javacVerbose" value="false" />
<!-- Set global properties for this build -->
<property name="src" value="harness-src" />
<property name="src.tests" value="examples-src" />
<property name="build" value="build" />
<property name="build.result" value="${basedir}" />
<property name="build.tests" value="build/tests" />
<property name="build.javadocs" value="${build}/javadocs" />
<property name="templates" value="../com.ibm.safe/templates"/>
<property name="specifications" value="../com.ibm.safe/specifications"/>
<property name="dist" value="dist" />
<property name="etc" value="etc" />
<property name="dat" value="dat" />
<property name="docs" value="docs" />
<property name="lib" value="lib" />
<property name="mainlib" value="../mainlib" />
<property name="sharedlib" value="../sharedlib" />
<property name="testdata" value="../testdata/safe" />
<property name="resultdir" value="${build}/output/" />
<property name="publish.javadocs" value="javadocs/com.ibm.domo.js.test" />
<property name="safescope" value="${sharedlib}/domojscore.jar" />
<property name="saferules" value="${specifications}/rules/rules.xml" />
<property name="saferesultdir" value="${resultdir}" />
<property name="saferesultfilename" value="domojscore.xml"/>
<property name="excluded-tests-file" value="excluded-tests.txt" />
<property name="cvsroot" value="/gsa/watgsa/home/d/o/dolby/cvs/JTD"/>
<import file="${sharedlib}/scripts/common-tests-targets.xml"/>
</project>

View File

@ -0,0 +1,91 @@
function testSwitch( x ) {
var result = -1;
switch ( x ) {
case 3:
result = 7;
case 4:
case 5: {
result = result+3;
break;
}
case 6:
result = 2;
default:
result += 4;
}
return result;
}
function testDoWhile( x ) {
var result = 6;
do {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
} while (--x > 4);
return result;
}
function testWhile( x ) {
var result = 6;
while (--x > 4) {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
}
return result;
}
function testFor( x ) {
for(var result = 6; x > 4; x--) {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
}
return result;
}
function testReturn( x ) {
if (x < 17)
return 8;
x++;
return x;
}
function testDeadLoop( x ) {
while (x < 17) {
return x++;
}
while (x < 17) {
if (x != 5) continue;
return x++;
}
return 0;
}
testSwitch( 7 );
testDoWhile( 5 );
testWhile( 11 );
testFor( 16 );
testReturn( 2 );
testDeadLoop( 12 );

View File

@ -0,0 +1,12 @@
function testForIn( x ) {
var z;
for(var y in x) {
z = (x[y])();
}
}
testForIn({
foo: function testForIn1() { return 7; },
bar: function testForIn2() { return "whatever"; }
});

View File

@ -0,0 +1,16 @@
function outer(outerArg) {
var local = 3;
function inner1(inner1Arg) {
outerArg = inner1Arg + 1;
};
var fun = function(inner2Arg) { return inner2Arg + outerArg; };
inner1( fun(6) );
}

View File

@ -0,0 +1,45 @@
function Polygon() {
this.edges = 8;
this.regular = false;
this.shape = function shape() { return "rectangle"; };
this.area = function area() { return -1; };
}
function objectMasquerading () {
function Rectangle(top_len,side_len) {
this.temp = Polygon;
this.temp();
this.temp = null;
this.edges = 4;
this.top = top_len;
this.side = side_len;
this.area = function area() { return this.top*this.sides; };
}
return new Rectangle(3, 5);
}
function sharedClassObject() {
function Rectangle(top_len, side_len) {
this.edges = 4;
this.top = top_len;
this.side = side_len;
this.area = function area() { return this.top*this.sides; };
}
Rectangle.prototype = new Polygon();
return new Rectangle(3, 7);
}
var rec1 = objectMasquerading();
rec1.area();
rec1.shape();
var rec2 = sharedClassObject();
rec2.area();
rec2.shape();

View File

@ -0,0 +1,115 @@
function testSwitch( x ) {
var result = -1;
switch ( x ) {
case 3:
result = 7;
case 4:
case 5: {
result = result+3;
break;
}
case 6:
result = 2;
default:
result += 4;
}
return result;
}
function testIfConvertedSwitch( x, y ) {
var result = -1;
switch ( x ) {
case y:
result = 7;
case y+1:
case y+2: {
result = result+3;
break;
}
case y-1:
result = 2;
default:
result += 4;
}
return result;
}
function testDoWhile( x ) {
var result = 6;
do {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
} while (--x > 4);
return result;
}
function testWhile( x ) {
var result = 6;
while (--x > 4) {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
}
return result;
}
function testFor( x ) {
for(var result = 6; x > 4; x--) {
if (x > 100)
continue;
else if (x < 0)
break;
else
result += 1;
}
return result;
}
function testReturn( x ) {
if (x < 17)
return 8;
x++;
return x;
}
function testDeadLoop( x ) {
while (x < 17) {
return x++;
}
while (x < 17) {
if (x != 5) continue;
return x++;
}
return 0;
}
testSwitch( 7 );
testIfConvertedSwitch( 7, 3 );
testDoWhile( 5 );
testWhile( 11 );
testFor( 16 );
testReturn( 2 );
testDeadLoop( 12 );

View File

@ -0,0 +1,12 @@
var fun1 = new Function("a", "b", "c", "return a+b+c");
var fun2 = new Function("a, b, c", "return a+b+c");
var fun3 = new Function("a, b", "c", "return a+b+c");
var x = fun1(5, 5, 6);
var y = fun2(5, 7, 1);
var z = fun3(3, 5, 2);

View File

@ -0,0 +1,46 @@
function objects_are_fun(arg1, arg2) {
var local = new Object();
var g = 7;
local.f = arg1.foo;
local.f();
local.otherMethod = function nothing(arg1) {
return arg1 - 7;
};
local[g] = arg2[ "bar" ];
local[g]();
}
var arg1;
var arg2 = new Object();
arg1 = {
foo: function whatever() {
return 3 + 7;
}
}
arg2.bar = function other() {
return this.otherMethod( 3 );
}
arg2.otherMethod = function something(arg1) {
return arg1 + 5;
}
arg2.bar( );
objects_are_fun( arg1, arg2 );
var numObj = new Number(4);
var strObj = new String("whatever");
var foo = strObj.toLowerCase();
var whatnot = [ , , , 7, numObj, arg2, strObj ];
whatnot[ 5 ].otherMethod( 7 );

View File

@ -0,0 +1,389 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<!--
Possible channels of interference, explored in this document or general properties we would like the portlet markup fragment to have
1. A global variable created in HEAD
2. A global built in object (e.g. navigator)
3. (Later)Access Keys, Tab Index (who wins if there is a conflict, eg. override Alt+F)
4. Dynamically modifying the DOM, Disallowed HTML Tags
5. Direct access by traversing the DOM Tree
6. (Later)Shared prototype objects
7. (Later)Cookies (essentially a global built in object which is writeable)
8. Reference to 'this'
9. The shared namespace, shared scope (understand how the scope works)
10. Dynamically add javascript event handlers.
11. Use of 'eval', self-modifying code
12. Shared style sheets
13. Access to shared library functions, eg. parseInt()
14. Maintain general structural integrity of the document - e.g. tags should appear where they should according to the DTD
TODO:
// creating a new function using a prototype, can the new function access the local variable of the event handler which creates the new function?
// when you create a new function in different html contexts, what is the value of this?
// The parser automatically inserts HTML Elements, e.g. TBODY in the table. We have to handle that. The swing html parser doesn't recognize TBODY, though.
-->
<style>
.test{color: red;}
.odd{background-color: white;}
.even{background-color: gray;}
</style>
<script language=javascript>
<!--
//
// 1. A global value that all portlets might need to access (read/write?)
// Global variable that the portal would like the portlets to make use of
// However, this like all other system objects should be made readonly by analysis
var now=new Date,t1=0;
t1=now.getTime();
-->
</script>
<title>Example Portal Page with two Portlets</title>
</head>
<body>
<table>
<tbody>
<tr>
<td>This will maliciously be removed by a portlet if you click on the text in the gray box</td><td>That should be avoided</td>
</tr>
<tr>
<td width="40%" class=odd>
<div>
<!-- Start: Portlet 1 Markup Fragment -->
<script type="text/javascript">
<!--
// 2. Use of a system global object might be required. Such accesses should be made readonly
this.agt = navigator.userAgent.toLowerCase();
this.ie = (this.agt.indexOf("msie") != -1);
if(this.ie) {
document.write("<p>Sorry, we do not support Internet Explorer");
document.close();
} else {
document.write("<p>We applaud your taste in browsers!");
}
// The following line is erased using a style element in the malicious portlet
document.write("<p class=test>The time you started visiting this page is : " + t1 + "</p>");
-->
</script>
<h1>Plan a dinner with friends</h1><br>
<h2>Enter the names of Restaurants in order of descending preference</h2>
<form action="http://www.google.com/search" name=f onsubmit="sub(this);">
<input type=hidden name=hl value=en>
<input type=hidden name=q value="">
<script type="text/javascript">
<!--
var counter=2;
function sub(fm) {
var qstring = document.f.name1.value + " " + document.f.conf1.value + " restaurant ";
document.f.q.value = qstring;
var then = new Date;
alert("You took " + ((then.getTime()-t1)/1000) + " seconds to submit your preferences.");
return 1;
}
function createLinkElem(target, str) {
var moveElem = document.createElement("TD");
moveElem.appendChild(createLink(target, str));
return moveElem;
}
function createLink(target,str) {
var fnt = document.createElement("FONT");
fnt.setAttribute("size","-1");
fnt.appendChild(document.createTextNode(str));
var lnk = document.createElement("A");
lnk.setAttribute("href","#");
lnk.setAttribute("onclick",target);
lnk.appendChild(fnt);
return lnk;
}
function createInsertNode() {
var inElem = document.createElement("TR");
var elem = document.createElement("TD");
elem.setAttribute("colspan","6");
elem.setAttribute("align","center");
var lnk = createLink("insertRow(this);","Insert Row");
// creating an event handler by directly assigning the value of the onclick property
lnk.onclick = iRow;
elem.appendChild(lnk);
inElem.appendChild(elem);
return inElem;
}
function iRow() {
insertRow(this);
}
function mUp() {
moveUp(this);
}
function boxNode(nm, str) {
var elem = document.createElement("TD");
var inp = document.createElement("INPUT");
inp.setAttribute("maxlength","2048");
inp.setAttribute("size","55");
inp.setAttribute("name",nm);
inp.setAttribute("value","");
inp.setAttribute("title",str);
elem.appendChild(inp);
return elem;
}
function createRow(num) {
var newElem = document.createElement("TR");
var lnk = createLinkElem("moveUp(this);", "Move Up");
// creating an event handler using the addEventListener method
lnk.addEventListener('click', mUp, false);
newElem.appendChild(lnk);
var elemChild = document.createElement("TD");
elemChild.appendChild(document.createTextNode(num));
newElem.appendChild(elemChild);
newElem.appendChild(boxNode("name"+num,"Name "+num));
newElem.appendChild(boxNode("conf"+num,"Location "+num));
newElem.appendChild(createLinkElem("moveDown(this);","Move Down"));
newElem.appendChild(createLinkElem("deleteElem(this);","Delete Row"));
newElem.setAttribute("id","bar");
newElem.setAttribute("index",num);
newElem.setAttribute("rowIndex", 5);
alert(newElem.getAttribute("rowIndex"));
return newElem;
}
function insertRow(telement) {
var chld = getRow(telement);
var par = chld.parentNode;
var prev = prevRow(chld);
var numE,num;
if(prev) {
numE = prev.cells[1];
var num = numE.firstChild.nodeValue;
if(num=="Rank") {
num = 1;
} else {
num = parseInt(numE.firstChild.nodeValue) + 1;
}
} else {
num = 1;
}
par.insertBefore(createInsertNode(), chld);
par.insertBefore(createRow(num), chld);
chld = nextRow(chld);
while(chld) {
incNumber(chld, true);
chld = nextRow(chld);
}
}
function incNumber(trow, inc) {
if(trow.cells.length != 6) return;
// alert("before removing" + trow.getAttribute("id") + " = " + trow.id);
// trow.id = null;
// alert("after removing" + trow.getAttribute("id") + " = " + trow.id);
// alert("before removing" + trow.getAttribute("index") + " = " + trow.index);
// trow.index = null;
// alert("after removing" + trow.getAttribute("index") + " = " + trow.index);
alert(trow.getAttribute("rowIndex"));
var node = trow.cells[1];
var num = node.firstChild.nodeValue;
num = parseInt(num);
if(inc) {
num++;
} else {
num--;
}
trow.setAttribute("index", num);
node.firstChild.nodeValue=num+".";
node = trow.cells[2];
node = node.firstChild;
node.setAttribute("name","name"+num);
node.setAttribute("title","Name "+num);
node = trow.cells[3];
node = node.firstChild;
node.setAttribute("name","conf"+num);
node.setAttribute("title","Location "+num);
}
function prevRow(telement) {
if(!telement) {
return null;
}
var prev = telement.previousSibling;
while(prev && prev.nodeName != "TR") {
prev = prev.previousSibling;
}
return prev;
}
function nextRow(telement) {
if(!telement) {
return null;
}
var next = telement.nextSibling;
while(next && next.nodeName != "TR") {
next = next.nextSibling;
}
return next;
}
function getRow(telement) {
var chld = telement.parentNode;
while(chld.nodeName != "TR") {
chld = chld.parentNode;
}
return chld;
}
function moveUp(telement) {
var trow = getRow(telement);
var prev = prevRow(prevRow(trow));
var par = trow.parentNode;
if(prevRow(prev)) {
incNumber(trow,false);
incNumber(prev,true);
var next = nextRow(trow);
var remove = par.removeChild(trow);
par.insertBefore(remove,prev);
remove = par.removeChild(prev);
par.insertBefore(remove,next);
}
}
function moveDown(telement) {
var trow = getRow(telement);
var next = nextRow(nextRow(trow));
var par = trow.parentNode;
if(next) {
incNumber(trow,true);
incNumber(next,false);
var follo = nextRow(trow);
var remove = par.removeChild(trow);
par.insertBefore(remove,next);
remove = par.removeChild(next);
par.insertBefore(remove,follo);
}
}
function deleteElem(telement) {
var tr = getRow(telement);
follow = nextRow(tr);
var par = tr.parentNode;
var prev = prevRow(tr);
par.removeChild(prev);
par.removeChild(tr);
while(follow) {
incNumber(follow, false);
follow = nextRow(follow);
}
}
-->
</script>
<table>
<tbody>
<tr>
<td>&nbsp;</td><td align=center>Rank</td> <td align=center>Name of Restaurant</td> <td align=center>Location</td><td>&nbsp;</td><td>&nbsp;</td>
</tr>
<tr><td colspan=6 align=center><a href="#" onclick="insertRow(this);"><font size="-1">Insert Row</font></a></td></tr>
<tr id="bar" rowIndex="5">
<td><a href="#" onclick="moveUp(this);"><font size="-1">Move Up</font></a></td>
<td>1.</td>
<td><input maxlength=2048 size=55 name="name1" value="" title="Name 1"></td>
<td><input maxlength=2048 size=55 name="conf1" value="" title="Location 1"></td>
<td><font size="-1"><a href="#" onclick="moveDown(this);">Move Down</a></font></td>
<td><font size="-1"><a href="#" onclick="deleteElem(this);">Delete Row</a></font>
</tr>
<tr><td colspan=6 align=center><a href="#" onclick="insertRow(this);"><font size="-1">Insert Row</font></a></td></tr>
</tbody>
</table>
<p><center><input type=submit value="Submit Preferences" name=btnI></center>
</form>
<!-- End: Portlet 1 Markup Fragment -->
</div>
</td>
<td width="40%" class=even>
<div>
<!-- Start Portlet 2 Markup Fragment -->
<p id="secret" onclick="malicious(this)">This portlet contains information that is top secret. Thou shalt not read it</p>
<!-- Malicious style element -->
<!--
<style>
.test{color: white;}
</style>
-->
<script type="text/javascript">
<!--
function malicious(elem) {
var par = elem.parentNode;
// Creating a disallowed tag
var base = document.createElement("BASE");
base.setAttribute("href","http://www.hacker.com/");
par.appendChild(base);
// create a table
// var tab = document.createElement("TABLE");
// var tbody = document.createElement("TBODY");
// var tr = document.createElement("TR");
var td = document.createElement("TD");
var txt = document.createTextNode("Text");
td.appendChild(txt);
// tr.appendChild(td);
// tbody.appendChild(tr);
// tab.appendChild(td);
par.appendChild(td);
// TBODY is not automatically inserted
// Accessing and messing with other parts of the tree
while(par.nodeName != "TBODY") {
par = par.parentNode;
}
// anything outside the Restricted DOM Spec should be disallowed
par.firstChild.innerHTML = "This is crazy!";
alert(par.firstChild);
par.removeChild(par.firstChild);
}
// The following line writes into a shared global variable, and should be stopped
t1 = 1000;
// Write access to system level objects should be disallowed
window.status = "Malicious Portlet";
-->
</script>
<!-- End: Portlet 2 Markup Fragment -->
</div>
</td>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,72 @@
function outer( x ) {
x++;
var z = x;
function inner( y ) {
x += y;
z += 1
x++
};
var innerName = inner;
function inner2( y ) {
if (y < 3) innerName = inner3;
innerName( y );
}
function inner3( y ) {
for(x = 0; x < 10; x++) {
y++;
}
}
inner2( x );
inner( 7 );
inner3( 2 );
(function indirect( f, x ) { f(x); })( innerName, 6 );
function level1() {
function level5() {
x++;
return x;
}
function level4() {
return level5();
}
function level3() {
if (x == 3) {
level4();
}
return x;
}
function level2() {
if (x > 2) {
level3();
return x;
} else {
return 7;
}
}
x++;
if (x < 7) {
level2();
}
return x;
}
level1();
return x+z;
}
var result = outer( 5 );

View File

@ -0,0 +1,94 @@
function trivial(one, two) {
var local = two + 7;
if (local > 5)
return one;
else {
return function inc(i) { return i + 1; } ( two );
}
}
function silly(one, two) {
var local = two + 7;
var result;
if (local > Math.E)
result = --two;
else {
result = 5;
result = result<<1;
}
return result;
}
var weird = function weirder ( one ) {
var result = Math.abs( one );
var i;
for(i = 0; i < 7; i++) {
if ( ! ( (one + i) < 5 ) ) {
result = (6, result / i);
}
}
return result;
}
var strange = function stranger ( one ) {
var result = ~one;
result /= 7;
var i = 0;
do {
if ( (one * i) < -5 ) {
result = result % i;
}
} while (++i <= 7);
return result;
}
var fun = function fib(x) {
return (x < 2)? 1: (fib(x-1) + fib(x-2));
}
function bad(one, two) {
var local = one + 7;
var result;
switch (local) {
case 1:
case 2:
case 3:
case 4:
result = +5;
result = result>>>2;
break;
case 5:
case 6:
case 7:
result = two>>1;
break;
default:
result =-1;
}
return result;
}
function rubbish(one, two) {
if (one(5))
return one( 3 );
else
return rubbish(two, one);
}
rubbish(strange, weird);
var F;
if ( bad(2, 3) )
F = fun;
else
F = strange;
trivial(3, 2);
if ( F(6) != 0 )
bad(4, 5);
else
weird( silly( "whatever", 7 ) );

View File

@ -0,0 +1,87 @@
function trivial(one, two) {
var local = two + 7;
if (local > 5)
return one;
else {
return two;
}
}
function silly(one, two) {
var local = two + 7;
var result = 0;
if (local > Math.E)
result = --two;
else {
result = 5;
result = result<<1;
}
return result;
}
function weirder ( one ) {
var result = Math.abs( one );
for(var i = 0; i < 7; i++) {
if ( ! ( (one + i) < 5 ) ) {
result = (6, result / i);
} else {
result = 7;
}
}
return result;
}
function stranger ( one ) {
var result = ~one;
result /= 7;
var i = 0;
do {
if ( (one * i) < -5 ) {
result = result % i;
} else {
result = 4;
}
} while (++i <= 7);
return result;
}
function fib(x) {
return (x < 2)? 1: (fib(x-1) + fib(x-2));
}
function bad(one, two) {
var local = one + 7;
var result = 0;
switch (local) {
case 1:
case 2:
case 3:
case 4:
result = +5;
result = result>>>2;
break;
case 5:
case 6:
case 7:
result = two>>1;
break;
default:
result =-1;
}
return result;
}
function rubbish(one, two) {
if (one(5))
return one( 3 );
else
return rubbish(two, one);
}
rubbish(stranger, weirder);
trivial(3, 2);
bad(4, 5);
weirder( silly( "whatever", 7 ) );

View File

@ -0,0 +1,13 @@
function getOp(x, op) {
return x[ "operator" + op ];
}
function plusNum(y) {
return this.val + y;
}
var obj = { val: 7, operatorPlus: plusNum };
var result = ( getOp(obj, "Plus") )( 6 );

View File

@ -0,0 +1,9 @@
var stuff = new String("this is a string of words");
var words = stuff.split(" ");
var firstWord = words[0];
var firstWordUpper = firstWord.toUpperCase();

View File

@ -0,0 +1,76 @@
function targetOne( x ) {
return x;
}
function targetTwo( x ) {
throw x;
}
function tryCatch( x, targetOne, targetTwo ) {
try {
if (x.one < 7)
targetOne( x );
else
targetTwo( x );
} catch (e) {
e.two();
}
}
function tryFinally( x, targetOne, targetTwo ) {
try {
if (x.one < 7)
return targetOne( x );
else
targetTwo( x );
} finally {
x.two();
}
x.three();
}
function tryFinallyLoop( x, targetTwo ) {
while (x.one < 7) {
try {
if (x.one < 3)
break;
else
targetTwo( x );
} finally {
x.two();
}
}
}
function tryCatchFinally( x, targetOne, targetTwo ) {
try {
if (x.one < 7)
targetOne( x );
else
targetTwo( x );
} catch (e) {
e.two();
} finally {
x.three();
}
}
o = {
one: -12,
two: function two () {
return this;
},
three: function three () {
return 8;
}
};
tryCatch(o, targetOne, targetTwo);
tryFinally(o, targetOne, targetTwo);
tryFinallyLoop(o, targetTwo);
tryCatchFinally(o, targetOne, targetTwo);

View File

@ -0,0 +1,17 @@
function Obj(x) {
var state = x;
this.set = function set(x) { state = x; };
this.get = function get() { return state; };
};
var obj = new Obj( function tester1() { return 3; } );
var test1 = ( obj.get() )();
obj.set( function tester2() { return 7; } );
var test2 = ( obj.get() )();

View File

@ -0,0 +1,83 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
import java.util.*;
/**
* The main plugin class to be used in the desktop.
*/
public class JavaScriptTestPlugin extends Plugin {
//The shared instance.
private static JavaScriptTestPlugin plugin;
//Resource bundle.
private ResourceBundle resourceBundle;
/**
* The constructor.
*/
public JavaScriptTestPlugin() {
super();
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
resourceBundle = null;
}
/**
* Returns the shared instance.
*/
public static JavaScriptTestPlugin getDefault() {
return plugin;
}
/**
* Returns the string from the plugin's resource bundle,
* or 'key' if not found.
*/
public static String getResourceString(String key) {
ResourceBundle bundle = JavaScriptTestPlugin.getDefault().getResourceBundle();
try {
return (bundle != null) ? bundle.getString(key) : key;
} catch (MissingResourceException e) {
return key;
}
}
/**
* Returns the plugin's resource bundle,
*/
public ResourceBundle getResourceBundle() {
try {
if (resourceBundle == null)
resourceBundle = ResourceBundle.getBundle("com.ibm.domo.js.test.JavaScriptTestPluginResources");
} catch (MissingResourceException x) {
resourceBundle = null;
}
return resourceBundle;
}
}

View File

@ -0,0 +1,52 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import com.ibm.wala.cast.js.translator.*;
import com.ibm.wala.ipa.callgraph.*;
import java.io.*;
import java.net.*;
public class TestAjaxsltCallGraphShape extends TestCallGraphShape {
public static void main(String[] args) {
justThisTest(TestAjaxsltCallGraphShape.class);
}
public void setUp() {
Util.setTranslatorFactory(
new JavaScriptTranslatorFactory.CAstRhinoFactory());
}
private static final Object[][] assertionsForAjaxslt = new Object[][] {
};
public void testAjaxslt() throws IOException {
URL url =
getClass().getClassLoader().getResource("ajaxslt/test/xslt.html");
CallGraph CG = Util.makeHTMLCG( url );
verifyGraphAssertions(CG, assertionsForAjaxslt);
}
private static final Object[][] assertionsForAjaxpath = new Object[][] {
};
public void testAjaxpath() throws IOException {
URL url =
getClass().getClassLoader().getResource("ajaxslt/test/xpath.html");
CallGraph CG = Util.makeHTMLCG( url );
verifyGraphAssertions(CG, assertionsForAjaxpath);
}
}

View File

@ -0,0 +1,110 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import com.ibm.wala.util.debug.Trace;
import com.ibm.wala.util.collections.*;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.core.tests.util.WalaTestCase;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.*;
import com.ibm.wala.ssa.*;
import com.ibm.wala.util.warnings.WarningSet;
import java.util.*;
import junit.framework.Assert;
public abstract class TestCallGraphShape extends WalaTestCase {
protected static class Name {
String name;
int instructionIndex;
int vn;
Name(int vn, int instructionIndex, String name) {
this.vn = vn;
this.name = name;
this.instructionIndex = instructionIndex;
}
}
protected void verifyNameAssertions(CallGraph CG, Object[][] assertionData) {
WarningSet W = new WarningSet();
for(int i = 0; i < assertionData.length; i++) {
Iterator NS = Util.getNodes(CG, (String)assertionData[i][0]).iterator();
while ( NS.hasNext() ) {
CGNode N = (CGNode) NS.next();
IR ir = ((SSAContextInterpreter)CG.getInterpreter(N)).getIR(N, W);
Name[] names = (Name[]) assertionData[i][1];
for(int j = 0; j < names.length; j++) {
Trace.println("looking for " + names[j].name + ", " + names[j].vn + " in " + N);
String[] localNames = ir.getLocalNames( names[j].instructionIndex, names[j].vn );
boolean found = false;
for(int k = 0; k < localNames.length; k++) {
if ( localNames[k].equals(names[j].name) ) {
found = true;
}
}
Assert.assertTrue("no name " + names[j].name + " for " + N, found);
}
}
}
}
protected void verifyGraphAssertions(CallGraph CG, Object[][] assertionData) { Trace.println( CG );
for(int i = 0; i < assertionData.length; i++) {
check_target:
for(int j = 0; j < ((String[])assertionData[i][1]).length; j++) {
Iterator srcs =
(assertionData[i][0] instanceof String)?
Util.getNodes(CG, (String)assertionData[i][0]).iterator():
new NonNullSingletonIterator( CG.getFakeRootNode() );
Assert.assertTrue("cannot find " + assertionData[i][0], srcs.hasNext());
while (srcs.hasNext()) {
CGNode src = (CGNode)srcs.next();
for(Iterator sites = src.iterateSites(); sites.hasNext(); ) {
CallSiteReference sr = (CallSiteReference) sites.next();
Iterator dsts = Util.getNodes(CG, ((String[])assertionData[i][1])[j]).iterator();
Assert.assertTrue("cannot find " + ((String[])assertionData[i][1])[j], dsts.hasNext());
while (dsts.hasNext()) {
CGNode dst = (CGNode)dsts.next();
for(Iterator tos = src.getPossibleTargets(sr).iterator();
tos.hasNext(); )
{
if (tos.next().equals(dst)) {
Trace.println("found expected " + src + " --> " + dst + " at " + sr);
continue check_target;
}
}
}
}
}
Assert.assertTrue("cannot find edge " + assertionData[i][0] + " ---> " + ((String[])assertionData[i][1])[j], false);
}
}
}
protected static final Object ROOT = new Object();
}

View File

@ -0,0 +1,259 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import com.ibm.wala.cast.js.translator.*;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.*;
import java.io.*;
public class TestSimpleCallGraphShape extends TestCallGraphShape {
public static void main(String[] args) {
justThisTest(TestSimpleCallGraphShape.class);
}
public void setUp() {
Util.setTranslatorFactory(
new JavaScriptTranslatorFactory.CAstRhinoFactory());
}
protected static final Object[][] assertionsForSimple = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/simple.js"}},
new Object[]{"tests/simple.js",
new String[]{"tests/simple.js/bad",
"tests/simple.js/silly",
"tests/simple.js/fib",
"tests/simple.js/stranger",
"tests/simple.js/trivial",
"tests/simple.js/rubbish",
"tests/simple.js/weirder"}},
new Object[]{"tests/simple.js/trivial",
new String[]{"tests/simple.js/trivial/inc"}},
new Object[]{"tests/simple.js/rubbish",
new String[]{"tests/simple.js/weirder",
"tests/simple.js/stranger",
"tests/simple.js/rubbish"}},
new Object[]{"tests/simple.js/fib",
new String[]{"tests/simple.js/fib"}},
new Object[]{"tests/simple.js/weirder",
new String[]{"prologue.js/abs"}}
};
public void testSimple() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "simple.js");
verifyGraphAssertions(CG, assertionsForSimple);
}
private static final Object[][] assertionsForObjects = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/objects.js"}},
new Object[]{"tests/objects.js",
new String[]{"tests/objects.js/objects_are_fun",
"tests/objects.js/other",
"tests/objects.js/something"}},
new Object[]{"tests/objects.js/other",
new String[]{"tests/objects.js/something",
"tests/objects.js/objects_are_fun/nothing"}},
new Object[]{"tests/objects.js/objects_are_fun",
new String[]{"tests/objects.js/other",
"tests/objects.js/whatever"}}};
public void testObjects() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "objects.js");
verifyGraphAssertions(CG, assertionsForObjects);
}
private static final Object[][] assertionsForInherit = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/inherit.js"}},
new Object[]{"tests/inherit.js",
new String[]{"tests/inherit.js/objectMasquerading",
"tests/inherit.js/objectMasquerading/Rectangle/area",
"tests/inherit.js/Polygon/shape",
"tests/inherit.js/sharedClassObject",
"tests/inherit.js/sharedClassObject/Rectangle/area"}},
/*
new Object[]{"tests/inherit.js/objectMasquerading",
new String[]{"ctor:tests/inherit.js/objectMasquerading/Rectangle"}},
new Object[]{"tests/inherit.js/sharedClassObject",
new String[]{"ctor:tests/inherit.js/sharedClassObject/Rectangle"}},
*/
};
public void testInherit() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "inherit.js");
verifyGraphAssertions(CG, assertionsForInherit);
}
private static final Object[][] assertionsForNewfn = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/newfn.js"}},
new Object[]{"tests/newfn.js",
new String[]{"ctor 1/_fromctor",
"ctor 2/_fromctor",
"ctor 3/_fromctor"}}
};
public void testNewfn() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "newfn.js");
verifyGraphAssertions(CG, assertionsForNewfn);
}
private static final Object[][] assertionsForControlflow = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/control-flow.js"}},
new Object[]{"tests/control-flow.js",
new String[]{"tests/control-flow.js/testSwitch",
"tests/control-flow.js/testDoWhile",
"tests/control-flow.js/testWhile",
"tests/control-flow.js/testFor",
"tests/control-flow.js/testReturn"}}
};
public void testControlflow() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "control-flow.js");
verifyGraphAssertions(CG, assertionsForControlflow);
}
private static final Object[][] assertionsForMoreControlflow = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/more-control-flow.js"}},
new Object[]{"tests/more-control-flow.js",
new String[]{"tests/more-control-flow.js/testSwitch",
"tests/more-control-flow.js/testIfConvertedSwitch",
"tests/more-control-flow.js/testDoWhile",
"tests/more-control-flow.js/testWhile",
"tests/more-control-flow.js/testFor",
"tests/more-control-flow.js/testReturn"}}
};
public void testMoreControlflow() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "more-control-flow.js");
verifyGraphAssertions(CG, assertionsForMoreControlflow);
}
private static final Object[][] assertionsForForin = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/forin.js"}},
new Object[]{"tests/forin.js",
new String[]{"tests/forin.js/testForIn"}},
new Object[]{"tests/forin.js/testForIn",
new String[]{"tests/forin.js/testForIn1",
"tests/forin.js/testForIn2"}}
};
public void testForin() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "forin.js");
verifyGraphAssertions(CG, assertionsForForin);
}
private static final Object[][] assertionsForSimpleLexical = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/simple-lexical.js"}},
new Object[]{"tests/simple-lexical.js",
new String[]{"tests/simple-lexical.js/outer"}},
new Object[]{"tests/simple-lexical.js/outer",
new String[]{"tests/simple-lexical.js/outer/indirect",
"tests/simple-lexical.js/outer/inner",
"tests/simple-lexical.js/outer/inner2",
"tests/simple-lexical.js/outer/inner3"}},
new Object[]{"tests/simple-lexical.js/outer/indirect",
new String[]{"tests/simple-lexical.js/outer/inner",
"tests/simple-lexical.js/outer/inner3"}},
new Object[]{"tests/simple-lexical.js/outer/inner2",
new String[]{"tests/simple-lexical.js/outer/inner",
"tests/simple-lexical.js/outer/inner3"}}
};
public void testSimpleLexical() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "simple-lexical.js");
verifyGraphAssertions(CG, assertionsForSimpleLexical);
}
private static final Object[][] assertionsForTry = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/try.js"}},
new Object[]{"tests/try.js",
new String[]{"tests/try.js/tryCatch",
"tests/try.js/tryFinally",
"tests/try.js/tryCatchFinally"}},
new Object[]{"tests/try.js/tryCatch",
new String[]{"tests/try.js/targetOne",
"tests/try.js/targetTwo",
"tests/try.js/two"}},
new Object[]{"tests/try.js/tryFinally",
new String[]{"tests/try.js/targetOne",
"tests/try.js/targetTwo",
"tests/try.js/two"}},
new Object[]{"tests/try.js/tryCatchFinally",
new String[]{"tests/try.js/targetOne",
"tests/try.js/targetTwo",
"tests/try.js/three",
"tests/try.js/two"}}
};
public void testTry() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "try.js");
verifyGraphAssertions(CG, assertionsForTry);
}
private static final Object[][] assertionsForStringOp = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/string-op.js"}},
new Object[]{"tests/string-op.js",
new String[]{"tests/string-op.js/getOp",
"tests/string-op.js/plusNum"}}
};
public void testStringOp() throws IOException {
PropagationCallGraphBuilder B =
Util.makeScriptCGBuilder("tests", "string-op.js");
B.getOptions().setTraceStringConstants( true );
CallGraph CG = B.makeCallGraph( B.getOptions() );
verifyGraphAssertions(CG, assertionsForStringOp);
}
private static final Object[][] assertionsForUpward = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/upward.js"}},
new Object[]{"tests/upward.js",
new String[]{"tests/upward.js/Obj/set",
"tests/upward.js/Obj/get",
"tests/upward.js/tester1",
"tests/upward.js/tester2"}}
};
public void testUpward() throws IOException {
CallGraph CG = Util.makeScriptCG("tests", "upward.js");
verifyGraphAssertions(CG, assertionsForUpward);
}
private static final Object[][] assertionsForStringPrims = new Object[][] {
new Object[]{ROOT,
new String[]{"tests/string-prims.js"}},
new Object[]{"tests/string-prims.js",
new String[]{"prologue.js/stringSplit",
"prologue.js/toUpperCase"}}
};
public void testStringPrims() throws IOException {
PropagationCallGraphBuilder B =
Util.makeScriptCGBuilder("tests", "string-prims.js");
B.getOptions().setTraceStringConstants( true );
CallGraph CG = B.makeCallGraph( B.getOptions() );
verifyGraphAssertions(CG, assertionsForStringPrims);
}
}

View File

@ -0,0 +1,36 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import com.ibm.wala.cast.js.util.WebUtil;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.core.tests.util.WalaTestCase;
import java.net.*;
import junit.framework.*;
public class TestWebUtil extends WalaTestCase {
public void testAjaxslt() {
URL url = getClass().getClassLoader().getResource("ajaxslt-0.4/test/xslt.html");
Assert.assertTrue(url != null);
Module mod = WebUtil.extractScriptFromHTML( url );
Assert.assertTrue(mod != null);
}
public void testAjaxpath() {
URL url = getClass().getClassLoader().getResource("ajaxslt-0.4/test/xpath.html");
Assert.assertTrue(url != null);
Module mod = WebUtil.extractScriptFromHTML( url );
Assert.assertTrue(mod != null);
}
}

View File

@ -0,0 +1,107 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.test;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.Trace;
import com.ibm.wala.cast.js.ipa.callgraph.*;
import com.ibm.wala.cast.js.loader.*;
import com.ibm.wala.cast.js.util.*;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.*;
import com.ibm.wala.ipa.callgraph.propagation.cfa.*;
import com.ibm.wala.ipa.cha.*;
import com.ibm.wala.util.warnings.WarningSet;
import java.io.*;
import java.net.*;
import java.util.*;
import junit.framework.Assert;
public class Util extends com.ibm.wala.cast.js.ipa.callgraph.Util {
public static PropagationCallGraphBuilder makeScriptCGBuilder(String dir, String name) throws IOException {
JavaScriptLoaderFactory loaders = Util.makeLoaders();
URL script =
Util.class.getClassLoader().getResource(dir + File.separator + name);
if (script == null) {
script = Util.class.getClassLoader().getResource(dir + "/" + name);
}
Assertions._assert(script != null, "cannot find " + dir + " and " + name);
AnalysisScope scope;
if (script.openConnection() instanceof JarURLConnection) {
scope = makeScope(new URL[]{ script }, loaders );
} else {
scope = makeScope(new SourceFileModule[]{ makeSourceModule(script, dir, name) }, loaders );
}
return makeCG(loaders, true, scope);
}
public static CallGraph makeScriptCG(String dir, String name) throws IOException {
PropagationCallGraphBuilder b = makeScriptCGBuilder(dir, name);
CallGraph CG = b.makeCallGraph( b.getOptions() );
dumpCG(b, CG);
return CG;
}
public static CallGraph makeScriptCG(SourceFileModule[] scripts) throws IOException {
PropagationCallGraphBuilder b = makeCGBuilder(scripts);
CallGraph CG = b.makeCallGraph( b.getOptions() );
dumpCG(b, CG);
return CG;
}
public static PropagationCallGraphBuilder makeHTMLCGBuilder(URL url) throws IOException {
SourceFileModule script = WebUtil.extractScriptFromHTML(url);
return makeCGBuilder(new SourceFileModule[]{ script });
}
public static CallGraph makeHTMLCG(URL url) throws IOException {
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url);
CallGraph CG = b.makeCallGraph( b.getOptions() );
dumpCG(b, CG);
return CG;
}
public static PropagationCallGraphBuilder makeCGBuilder(SourceFileModule[] scripts) throws IOException {
JavaScriptLoaderFactory loaders = makeLoaders();
AnalysisScope scope = makeScope(scripts, loaders );
return makeCG(loaders, true, scope);
}
protected static
PropagationCallGraphBuilder makeCG(JavaScriptLoaderFactory loaders,
boolean keepIRs,
AnalysisScope scope)
throws IOException
{
try {
WarningSet warnings = new WarningSet();
ClassHierarchy cha = makeHierarchy( scope, loaders, warnings );
Entrypoints roots = makeScriptRoots( cha );
AnalysisOptions options = makeOptions(scope, keepIRs, cha, roots, warnings);
JSCFABuilder builder = new JSZeroXCFABuilder(cha, warnings, options, null, null, null, ZeroXInstanceKeys.ALLOCATIONS);
return builder;
} catch (ClassHierarchyException e) {
Assert.assertTrue("internal error building class hierarchy", false);
return null;
}
}
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin
id="com.ibm.domo.js.test"
name="DOMO JavaScript Test Plug-in"
version="1.0.0"
provider-name="IBM"
class="com.ibm.wala.cast.js.test.JavaScriptTestPlugin">
<runtime>
<library name="test.jar"/>
</runtime>
<requires>
<import plugin="com.ibm.domo.js"/>
<import plugin="com.ibm.wala.cast"/>
<import plugin="com.ibm.wala.core"/>
<import plugin="org.eclipse.core.runtime"/>
<import plugin="com.ibm.wala.core.tests"/>
<import plugin="org.junit"/>
</requires>
</plugin>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.cast.js.test.TestSimpleCallGraphShape"/>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.cast.js.test"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.ibm.wala.cast.js.test"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
</launchConfiguration>