more work and tests on Web page model
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3991 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
205b7d078a
commit
23b669a691
|
@ -0,0 +1,60 @@
|
|||
|
||||
|
||||
(function () {
|
||||
|
||||
|
||||
var jQuery = window.jQuery = window.$ = function (selector, context) {
|
||||
return new jQuery.fn.init(selector, context);
|
||||
};
|
||||
|
||||
|
||||
var undefined;
|
||||
|
||||
jQuery.extend = jQuery.fn.extend = function () {
|
||||
var target = arguments[0] || {},
|
||||
i = 1,
|
||||
length = arguments.length,
|
||||
deep = false,
|
||||
options;
|
||||
if (target.constructor == Boolean) {
|
||||
deep = target;
|
||||
target = arguments[1] || {};
|
||||
i = 2;
|
||||
}
|
||||
if (typeof target != "object" && typeof target != "function") target = {};
|
||||
if (length == i) {
|
||||
target = this;
|
||||
--i;
|
||||
}
|
||||
for (; i < length; i++) if ((options = arguments[i]) != null) for (var name in options) {
|
||||
var src = target[name],
|
||||
copy = options[name];
|
||||
if (target === copy) continue;
|
||||
if (deep && copy && typeof copy == "object" && !copy.nodeType) {
|
||||
target[name] = jQuery.extend(deep, src || (copy.length != null ? [] : {}), copy);
|
||||
}
|
||||
else if (copy !== undefined) target[name] = copy;
|
||||
// else target[name] = copy;
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
jQuery.extend({
|
||||
speed: function (speed, easing, fn) {
|
||||
var opt = speed && speed.constructor == Object ? speed : {
|
||||
complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
|
||||
duration: speed,
|
||||
easing: fn && easing || easing && easing.constructor != Function && easing
|
||||
};
|
||||
opt.duration = (opt.duration && opt.duration.constructor == Number ? opt.duration : jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
|
||||
opt.old = opt.complete;
|
||||
opt.complete = function () {
|
||||
if (opt.queue !== false) jQuery(this).dequeue();
|
||||
if (jQuery.isFunction(opt.old)) opt.old.call(this);
|
||||
};
|
||||
return opt;
|
||||
},
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<HTML>
|
||||
<HEAD><TITLE>Login</TITLE></HEAD>
|
||||
<SCRIPT>
|
||||
function signon() {
|
||||
var form = document.forms[0];
|
||||
var elts = form.operation;
|
||||
for (var elt in elts) {
|
||||
if (elts[elt].checked==true) {
|
||||
window.open(elts[elt].value + ".php?user=" + form.user.value + "&pw=" + form.pw.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY>
|
||||
<FORM ID="theform" METHOD = "post" NAME = "login"
|
||||
ACTION="javascript: signon();">
|
||||
User Name: <INPUT TYPE = "text" NAME = "user"/><BR>
|
||||
Password: <INPUT TYPE = "password" NAME = "pw"/><BR>
|
||||
<INPUT TYPE="radio" NAME="operation" VALUE="query"/>Query
|
||||
<INPUT TYPE="radio" NAME="operation" VALUE="update"/>Update <BR>
|
||||
<INPUT TYPE="submit" NAME="Submit"/>
|
||||
</FORM>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<script src="2.js"> </script>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
asdasd
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,17 @@
|
|||
// $Id: drupal.js,v 1.41.2.4 2009/07/21 08:59:10 goba Exp $
|
||||
|
||||
var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} };
|
||||
|
||||
/**
|
||||
* Set the variable that indicates if JavaScript behaviors should be applied
|
||||
*/
|
||||
Drupal.jsEnabled = document.getElementsByTagName && document.createElement && document.createTextNode && document.documentElement && document.getElementById;
|
||||
|
||||
|
||||
|
||||
// Global Killswitch on the <html> element
|
||||
if (Drupal.jsEnabled) {
|
||||
//Do some code
|
||||
}
|
||||
|
||||
|
|
@ -11,12 +11,27 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.IVector;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.collections.SparseVector;
|
||||
import com.ibm.wala.util.intset.IntSetAction;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
@ -267,5 +282,59 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
Util.makeScriptCG("tests", "stack_overflow_on_ssa_conversion.js");
|
||||
// all we need is for it to finish building CG successfully.
|
||||
}
|
||||
|
||||
|
||||
private IVector<Set<Pair<CGNode, Integer>>> computeIkIdToVns(PointerAnalysis pa) {
|
||||
|
||||
// Created by reversing the points to mapping for local pointer keys.
|
||||
// Instead of mapping (local) pointer keys to instance keys (with id), we
|
||||
// map instance keys to VnInContext (which carry the same information as
|
||||
// local pointer keys)
|
||||
|
||||
final IVector<Set<Pair<CGNode, Integer>>> ret = new SparseVector<Set<Pair<CGNode, Integer>>>();
|
||||
|
||||
for (PointerKey pk : pa.getPointerKeys()) {
|
||||
if (pk instanceof LocalPointerKey) {
|
||||
|
||||
final LocalPointerKey lpk = (LocalPointerKey) pk;
|
||||
// we filter out local pointer keys that have no uses.
|
||||
// NOTE: do to some weird behavior, we get pointer keys with vns that
|
||||
// don't exist, so we have to filter those before asking about uses.
|
||||
if (lpk.getNode().getDU().getDef(lpk.getValueNumber()) != null) {
|
||||
Iterator<SSAInstruction> uses = lpk.getNode().getDU().getUses(lpk.getValueNumber());
|
||||
if (uses.hasNext()) {
|
||||
OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
|
||||
if (pointsToSet == null || pointsToSet.getBackingSet() == null)
|
||||
continue;
|
||||
pointsToSet.getBackingSet().foreach(new IntSetAction() {
|
||||
public void act(int ikId) {
|
||||
Set<Pair<CGNode, Integer>> s = ret.get(ikId);
|
||||
if (s == null) {
|
||||
s = HashSetFactory.make();
|
||||
ret.set(ikId, s);
|
||||
}
|
||||
s.add(Pair.make(lpk.getNode(), lpk.getValueNumber()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Test public void test214631() throws IOException, IllegalArgumentException, CancelException {
|
||||
JSCFABuilder b = Util.makeScriptCGBuilder("tests", "214631.js");
|
||||
b.makeCallGraph(b.getOptions());
|
||||
PointerAnalysis PA = b.getPointerAnalysis();
|
||||
// just make sure this does not crash
|
||||
computeIkIdToVns(PA);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,16 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
|||
verifyGraphAssertions(CG, assertionsForPage2);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForPage3 = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "page3.html" } }
|
||||
};
|
||||
|
||||
@Test public void testPage3() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||
CallGraph CG = Util.makeHTMLCG(url);
|
||||
verifyGraphAssertions(CG, assertionsForPage3);
|
||||
}
|
||||
|
||||
@Test public void testCrawl() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/crawl.html");
|
||||
CallGraph CG = Util.makeHTMLCG(url);
|
||||
|
@ -192,4 +202,24 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
|||
verifyGraphAssertions(CG, assertionsForPage17);
|
||||
}
|
||||
|
||||
/*
|
||||
@Test public void testDojoTest() throws IllegalArgumentException, IOException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/dojo/test.html");
|
||||
CallGraph CG = Util.makeHTMLCG(url);
|
||||
verifyGraphAssertions(CG, null);
|
||||
}
|
||||
*/
|
||||
|
||||
private static final Object[][] assertionsForApolloExample = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "apollo-example.html" } },
|
||||
new Object[] { "apollo-example.html", new String[] { "apollo-example.html/signon" } },
|
||||
new Object[] { "apollo-example.html/signon", new String[] { "preamble.js/DOMWindow/window_open" } }
|
||||
};
|
||||
|
||||
@Test public void testApolloExample() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/apollo-example.html");
|
||||
CallGraph CG = Util.makeHTMLCG(url);
|
||||
verifyGraphAssertions(CG, assertionsForApolloExample);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ function NamedNodeList() {
|
|||
}
|
||||
|
||||
function DOMNode() { // An impostor for the Node class
|
||||
this.attributes = new NamedNodeList();
|
||||
this.childNodes = new NamedNodeList();
|
||||
this.insertBefore = function insertBefore(newChild, refChild) {
|
||||
this.childNodes.insertBefore(newChild, refChild);
|
||||
|
@ -138,6 +137,7 @@ function DOMHTMLDocument() {
|
|||
this.temp();
|
||||
this.URL = new String();
|
||||
this.body = new HTMLBody();
|
||||
this.forms = new Array();
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,6 +183,7 @@ document.defaultView = window;
|
|||
window.XMLHttpRequest = XMLHttpRequest;
|
||||
|
||||
var dojo = new DOJOObj();
|
||||
|
||||
function DOMElement() { // An impostor for the Element class
|
||||
// inherits from Node
|
||||
this.temp = DOMNode;
|
||||
|
@ -192,14 +193,14 @@ function DOMElement() { // An impostor for the Element class
|
|||
// since that would be used as a workaround for eval
|
||||
|
||||
this.getAttribute = function getAttribute(name) {
|
||||
this.attributes.get(name);
|
||||
return this[name];
|
||||
}
|
||||
this.setAttribute = function setAttribute(name, value) {
|
||||
this.attributes.set(name, value);
|
||||
this[name] = value;
|
||||
}
|
||||
|
||||
this.removeAttribute = function removeAttribute(name) {
|
||||
this.attributes.remove(name);
|
||||
this[name] = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -215,34 +216,6 @@ function DOMHTMLElement() { // An impostor for the HTMLElement class
|
|||
this.lang = null;
|
||||
this.dir = null;
|
||||
this.className = null;
|
||||
|
||||
// Set Javascript properties
|
||||
this.getAttribute = function getAttribute(name) {
|
||||
if(name == "id") return this.id;
|
||||
else if(name == "title") return this.title;
|
||||
else if(name == "lang") return this.lang;
|
||||
else if(name == "dir") return this.dir;
|
||||
else if(name == "class") return this.className;
|
||||
else return this.attributes.get(name);
|
||||
}
|
||||
|
||||
this.setAttribute = function setAttribute(name, value) {
|
||||
if(name == "id") this.id = value;
|
||||
else if(name == "title") this.title = value;
|
||||
else if(name == "lang") this.lang = value;
|
||||
else if(name == "dir") this.dir = value;
|
||||
else if(name == "class") this.className = value;
|
||||
else return this.attributes.set(name, value);
|
||||
}
|
||||
|
||||
this.removeAttribute = function removeAttribute(name) {
|
||||
if(name == "id") this.id = null;
|
||||
else if(name == "title") this.title = null;
|
||||
else if(name == "lang") this.lang = null;
|
||||
else if(name == "dir") this.dir = null;
|
||||
else if(name == "class") this.className = null;
|
||||
else return this.attributes.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
var dynamic_node = 0;
|
||||
|
@ -265,11 +238,16 @@ function DOMHTMLGenericElement(tagName) {
|
|||
this.src.loadFile();
|
||||
}
|
||||
|
||||
var formCount = 0;
|
||||
|
||||
function DOMHTMLFormElement() {
|
||||
// inherits from HTMLElement
|
||||
this.temp = DOMHTMLElement;
|
||||
this.temp();
|
||||
|
||||
// add to 'forms' property
|
||||
document.forms[formCount++] = this;
|
||||
|
||||
// Set Javascript properties
|
||||
this.nodeName = "FORM";
|
||||
this.elements = new NamedNodeList();
|
||||
|
@ -288,37 +266,6 @@ function DOMHTMLFormElement() {
|
|||
this.enctype = "application/x-www-form-urlencoded";
|
||||
this.method = "get";
|
||||
this.target = null;
|
||||
|
||||
// Set Javascript properties
|
||||
this.getAttribute = function getAttribute(name) {
|
||||
if(name == "name") return this.name;
|
||||
else if(name == "accept-charset") return this.acceptCharset;
|
||||
else if(name == "action") return this.action;
|
||||
else if(name == "enctype") return this.enctype;
|
||||
else if(name == "method") return this.method;
|
||||
else if(name == "target") return this.target;
|
||||
else return this.prototype.getAttribute(name);
|
||||
}
|
||||
|
||||
this.setAttribute = function setAttribute(name, value) {
|
||||
if(name == "name") this.name = value;
|
||||
else if(name == "accept-charset") this.acceptCharset = value;
|
||||
else if(name == "action") this.action = value;
|
||||
else if(name == "enctype") this.enctype = value;
|
||||
else if(name == "method") this.method = value;
|
||||
else if(name == "target") this.target = value;
|
||||
else return this.prototype.setAttribute(name, value);
|
||||
}
|
||||
|
||||
this.removeAttribute = function removeAttribute(name) {
|
||||
if(name == "name") this.name = null;
|
||||
else if(name == "accept-charset") this.acceptCharset = null;
|
||||
else if(name == "action") this.action = null;
|
||||
else if(name == "enctype") this.enctype = null;
|
||||
else if(name == "method") this.method = null;
|
||||
else if(name == "target") this.target = null;
|
||||
else return this.prototype.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
|
||||
function DOMHTMLTableElement () {
|
||||
|
|
|
@ -15,7 +15,9 @@ import java.io.IOException;
|
|||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -23,6 +25,8 @@ import java.util.regex.Pattern;
|
|||
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
||||
import com.ibm.wala.cast.js.html.ITag;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class HTMLCallback implements IHtmlCallback {
|
||||
private final URL input;
|
||||
|
@ -132,6 +136,9 @@ public class HTMLCallback implements IHtmlCallback {
|
|||
return varName;
|
||||
}
|
||||
|
||||
private Stack<ITag> forms = new Stack<ITag>();
|
||||
private Set<Pair<ITag,String>> sets = new HashSet<Pair<ITag,String>>();
|
||||
|
||||
protected void writeElement(ITag tag, String cons, String varName) throws IOException {
|
||||
|
||||
indent(); domTreeFile.write("function make_" + varName + "(parent) {\n");
|
||||
|
@ -144,6 +151,34 @@ public class HTMLCallback implements IHtmlCallback {
|
|||
writeAttribute(tag, attr, value, "this", varName);
|
||||
}
|
||||
|
||||
if (tag.getName().equalsIgnoreCase("FORM")) {
|
||||
forms.push(tag);
|
||||
indent(); domTreeFile.write(" var currentForm = this;\n");
|
||||
} if (tag.getName().equalsIgnoreCase("INPUT")) {
|
||||
String prop = tag.getAttributeByName("NAME");
|
||||
if (prop == null) {
|
||||
prop = tag.getAttributeByName("name");
|
||||
}
|
||||
assert prop != null;
|
||||
|
||||
String type = tag.getAttributeByName("TYPE");
|
||||
if (type == null) {
|
||||
type = tag.getAttributeByName("type");
|
||||
}
|
||||
assert type != null;
|
||||
|
||||
if (type.equalsIgnoreCase("RADIO")) {
|
||||
if (! sets.contains(Pair.make(forms.peek(), prop))) {
|
||||
sets.add(Pair.make(forms.peek(), prop));
|
||||
indent(); domTreeFile.write(" currentForm." + prop + " = new Array();\n");
|
||||
indent(); domTreeFile.write(" currentForm." + prop + "Counter = 0;\n");
|
||||
}
|
||||
indent(); domTreeFile.write(" currentForm." + prop + "[currentForm." + prop + "Counter++] = this;\n");
|
||||
} else {
|
||||
indent(); domTreeFile.write(" currentForm." + prop + " = this;\n");
|
||||
}
|
||||
}
|
||||
|
||||
indent(); domTreeFile.write(" " + varName + " = this;\n");
|
||||
indent(); domTreeFile.write(" dom_nodes." + varName + " = this;\n");
|
||||
indent(); domTreeFile.write(" parent.appendChild(this);\n");
|
||||
|
@ -159,17 +194,21 @@ public class HTMLCallback implements IHtmlCallback {
|
|||
indent(); domTreeFile.write("function " + attr + "_" + varName2 + "(event) {" + value + "};\n");
|
||||
indent(); domTreeFile.write(varName + "." + attr + " = " + attr + "_" + varName2 + ";\n");
|
||||
entrypointFile.write("\n\n " + varName2 + "." + attr + "(null);\n\n");
|
||||
} else if (value.startsWith("javascript:") || value.startsWith("javaScript:")) {
|
||||
/*} else if (value.startsWith("javascript:") || value.startsWith("javaScript:")) {
|
||||
indent(); domTreeFile.write("var " + varName + attr + " = " + value.substring(11) + "\n");
|
||||
indent(); domTreeFile.write(varName + ".setAttribute('" + attr + "', " + varName + attr + ");\n");
|
||||
} else {
|
||||
*/} else {
|
||||
if (value.indexOf('\'') > 0) {
|
||||
value = value.replaceAll("\\'", "\\\\'");
|
||||
}
|
||||
if (value.indexOf('\n') > 0) {
|
||||
value = value.replaceAll("\\n", "\\\\n");
|
||||
}
|
||||
indent(); domTreeFile.write(varName + ".setAttribute('" + attr + "', '" + value + "');\n");
|
||||
if (attr.equals(attr.toUpperCase())) {
|
||||
attr = attr.toLowerCase();
|
||||
}
|
||||
// indent(); domTreeFile.write(varName + ".setAttribute('" + attr + "', '" + value + "');\n");
|
||||
indent(); domTreeFile.write(varName + "['" + attr + "'] = '" + value + "';\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +239,18 @@ public class HTMLCallback implements IHtmlCallback {
|
|||
|
||||
public void handleEndTag(ITag tag) {
|
||||
endElement(stack.pop());
|
||||
if (tag.getName().equalsIgnoreCase("FORM")) {
|
||||
forms.pop();
|
||||
}
|
||||
for(String v : tag.getAllAttributes().values()) {
|
||||
if (v.startsWith("javascript:")) {
|
||||
try {
|
||||
entrypointFile.write( v.substring(11) );
|
||||
} catch (IOException e) {
|
||||
Assertions.UNREACHABLE(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleStartTag(ITag tag) {
|
||||
|
|
Loading…
Reference in New Issue