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:
dolby-oss 2010-11-05 00:36:44 +00:00
parent 205b7d078a
commit 23b669a691
8 changed files with 276 additions and 67 deletions

View File

@ -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;
},
});
})();

View File

@ -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>

View File

@ -0,0 +1,8 @@
<HTML>
<HEAD>
<script src="2.js"> </script>
</HEAD>
<BODY>
asdasd
</BODY>
</HTML>

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 () {

View File

@ -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) {