diff --git a/com.ibm.wala.cast.js/.classpath b/com.ibm.wala.cast.js/.classpath index 5d720b119..1e05f7167 100644 --- a/com.ibm.wala.cast.js/.classpath +++ b/com.ibm.wala.cast.js/.classpath @@ -1,10 +1,10 @@ - - - - + + + + diff --git a/com.ibm.wala.cast.js/META-INF/MANIFEST.MF b/com.ibm.wala.cast.js/META-INF/MANIFEST.MF index a968c8e26..bb3ccdaa9 100644 --- a/com.ibm.wala.cast.js/META-INF/MANIFEST.MF +++ b/com.ibm.wala.cast.js/META-INF/MANIFEST.MF @@ -16,13 +16,13 @@ Export-Package: com.ibm.wala.cast.js, com.ibm.wala.cast.js.client.impl, com.ibm.wala.cast.js.html, com.ibm.wala.cast.js.html.jericho, + com.ibm.wala.cast.js.html.nu_validator, com.ibm.wala.cast.js.ipa.callgraph, com.ibm.wala.cast.js.ipa.summaries, com.ibm.wala.cast.js.loader, com.ibm.wala.cast.js.ssa, com.ibm.wala.cast.js.translator, com.ibm.wala.cast.js.types, - com.ibm.wala.cast.js.util, com.ibm.wala.cast.js.vis Require-Bundle: com.ibm.wala.cast, com.ibm.wala.core, diff --git a/com.ibm.wala.cast.js/build.xml b/com.ibm.wala.cast.js/build.xml index 966f45966..4ffa2b05b 100755 --- a/com.ibm.wala.cast.js/build.xml +++ b/com.ibm.wala.cast.js/build.xml @@ -1,69 +1,80 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/client/JavaScriptAnalysisEngine.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/client/JavaScriptAnalysisEngine.java index 4496c9489..2b323f9a2 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/client/JavaScriptAnalysisEngine.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/client/JavaScriptAnalysisEngine.java @@ -23,6 +23,7 @@ import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory; import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory; import com.ibm.wala.cast.js.types.JavaScriptTypes; import com.ibm.wala.classLoader.Module; +import com.ibm.wala.classLoader.SourceModule; import com.ibm.wala.client.AbstractAnalysisEngine; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.callgraph.AnalysisOptions; @@ -43,12 +44,11 @@ public class JavaScriptAnalysisEngine extends AbstractAnalysisEngine { public JavaScriptAnalysisEngine() { } - @SuppressWarnings("unchecked") public void buildAnalysisScope() { try { loaderFactory = new JavaScriptLoaderFactory(translatorFactory); - Module[] files = (Module[]) moduleFiles.toArray(new Module[moduleFiles.size()]); + SourceModule[] files = (SourceModule[]) moduleFiles.toArray(new SourceModule[moduleFiles.size()]); scope = new CAstAnalysisScope(files, loaderFactory, Collections.singleton(JavaScriptLoader.JS)); } catch (IOException e) { diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DefaultSourceExtractor.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DefaultSourceExtractor.java index 67de64282..75a1804f4 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DefaultSourceExtractor.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DefaultSourceExtractor.java @@ -1,11 +1,25 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; 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 com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.Pair; public class DefaultSourceExtractor extends DomLessSourceExtractor{ @@ -14,6 +28,9 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{ private final HashMap constructors = HashMapFactory.make(); protected final Stack stack; + private final Stack forms = new Stack(); + private final Set> sets = new HashSet>(); + public HtmlCallBack(URL entrypointUrl, IUrlResolver urlResolver) { super(entrypointUrl, urlResolver); @@ -27,7 +44,15 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{ public void handleEndTag(ITag tag) { super.handleEndTag(tag); endElement(stack.pop()); - } + if (tag.getName().equalsIgnoreCase("FORM")) { + forms.pop(); + } + for(String v : tag.getAllAttributes().values()) { + if (v != null && v.startsWith("javascript:")) { + entrypointRegion.println(v.substring(11), entrypointUrl, tag.getStartingLineNum()); + } + } + } @Override protected void handleDOM(ITag tag, String funcName) { @@ -48,7 +73,7 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{ if (relatedTag == null){ domRegion.println(indentedLine.toString()); } else { - domRegion.println(indentedLine.toString(), fileName, relatedTag.getStartingLineNum()); + domRegion.println(indentedLine.toString(), entrypointUrl, relatedTag.getStartingLineNum()); } } @@ -69,7 +94,35 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{ writeAttribute(tag, attr, value, "this", varName); } - printlnIndented("" + varName + " = this;", tag); + if (tag.getName().equalsIgnoreCase("FORM")) { + forms.push(tag); + printlnIndented(" var currentForm = this;", tag); + } if (tag.getName().equalsIgnoreCase("INPUT")) { + String prop = tag.getAttributeByName("NAME"); + if (prop == null) { + prop = tag.getAttributeByName("name"); + } + + String type = tag.getAttributeByName("TYPE"); + if (type == null) { + type = tag.getAttributeByName("type"); + } + + if (type != null && prop != null) { + if (type.equalsIgnoreCase("RADIO")) { + if (! sets.contains(Pair.make(forms.peek(), prop))) { + sets.add(Pair.make(forms.peek(), prop)); + printlnIndented(" currentForm." + prop + " = new Array();", tag); + printlnIndented(" currentForm." + prop + "Counter = 0;", tag); + } + printlnIndented(" currentForm." + prop + "[currentForm." + prop + "Counter++] = this;", tag); + } else { + printlnIndented(" currentForm." + prop + " = this;", tag); + } + } + } + + printlnIndented(varName + " = this;", tag); printlnIndented("dom_nodes." + varName + " = this;", tag); printlnIndented("parent.appendChild(this);", tag); } @@ -81,21 +134,19 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{ protected void writeEventAttribute(ITag tag, String attr, String value, String varName, String varName2){ if(attr.substring(0,2).equals("on")) { - printlnIndented("function " + attr + "_" + varName2 + "(event) {" + value + "};", tag); - printlnIndented(varName + "." + attr + " = " + attr + "_" + varName2 + ";", tag); - newLine(); newLine(); - printlnIndented(varName2 + "." + attr + "(null);\n", tag); - } else if (value.startsWith("javascript:") || value.startsWith("javaScript:")) { - printlnIndented("var " + varName + attr + " = " + value.substring(11), tag); - printlnIndented(varName + ".setAttribute('" + attr + "', " + varName + attr + ");", tag); - } else { + printlnIndented(varName + "." + attr + " = function " + attr + "_" + varName2 + "(event) {" + value + "};", tag); + entrypointRegion.println(varName2 + "." + attr + "(null);", entrypointUrl, new Integer(tag.getStartingLineNum())); + } else if (value != null) { if (value.indexOf('\'') > 0) { value = value.replaceAll("\\'", "\\\\'"); } if (value.indexOf('\n') > 0) { value = value.replaceAll("\\n", "\\\\n"); } - printlnIndented(varName + ".setAttribute('" + attr + "', '" + value + "');", tag); + if (attr.equals(attr.toUpperCase())) { + attr = attr.toLowerCase(); + } + printlnIndented(varName + "['" + attr + "'] = '" + value + "';", tag); } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DomLessSourceExtractor.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DomLessSourceExtractor.java index 56fa23084..797ce9170 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DomLessSourceExtractor.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/DomLessSourceExtractor.java @@ -1,10 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URL; @@ -12,17 +21,14 @@ import java.net.URLConnection; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.regex.Pattern; import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser; -import com.ibm.wala.classLoader.SourceFileModule; -import com.ibm.wala.util.collections.Pair; -public class DomLessSourceExtractor implements JSSourceExtractor { +public class DomLessSourceExtractor extends JSSourceExtractor { private static final Pattern LEGAL_JS_IDENTIFIER_REGEXP = Pattern.compile("[a-zA-Z$_][a-zA-Z\\d$_]*"); - private boolean DELETE_UPON_EXIT = true; - interface IGeneratorCallback extends IHtmlCallback { void writeToFinalRegion(SourceRegion finalRegion); } @@ -35,8 +41,8 @@ public class DomLessSourceExtractor implements JSSourceExtractor { protected final SourceRegion domRegion; protected final SourceRegion entrypointRegion; - protected final String fileName; - + private boolean inScriptRegion = false; + private int counter = 0; public HtmlCallback(URL entrypointUrl, IUrlResolver urlResolver) { @@ -45,19 +51,30 @@ public class DomLessSourceExtractor implements JSSourceExtractor { this.scriptRegion = new SourceRegion(); this.domRegion = new SourceRegion(); this.entrypointRegion = new SourceRegion(); - - this.fileName = entrypointUrl.getFile(); } //Do nothing - public void handleEndTag(ITag tag) {} + public void handleEndTag(ITag tag) { + if (tag.getName().equalsIgnoreCase("script")) { + assert inScriptRegion; + inScriptRegion = false; + } + } + + + public void handleText(int lineNumber, String text) { + if (inScriptRegion) { + scriptRegion.println(text, entrypointUrl, lineNumber); + } + } public void handleStartTag(ITag tag) { if (tag.getName().equalsIgnoreCase("script")) { handleScript(tag); + assert !inScriptRegion; + inScriptRegion = true; } handleDOM(tag); - } /** @@ -92,14 +109,14 @@ public class DomLessSourceExtractor implements JSSourceExtractor { if (attName.toLowerCase().startsWith("on") || (attValue != null && attValue.toLowerCase().startsWith("javascript:"))) { String fName = attName + "_" + funcName; String signatureLine = "function " + fName + "(event) {"; - domRegion.println(signatureLine, fileName, lineNum);// Defines the function + domRegion.println(signatureLine, entrypointUrl, lineNum);// Defines the function int offset = 0; for (String eventContentLine : extructJS(attValue)){ - domRegion.println("\t" + eventContentLine, fileName, lineNum + (offset++)); + domRegion.println("\t" + eventContentLine, entrypointUrl, lineNum + (offset++)); } - domRegion.println("}", fileName, lineNum);// Defines the function + domRegion.println("}", entrypointUrl, lineNum);// Defines the function - entrypointRegion.println("\t" + fName + "(null);", fileName, lineNum);// Run it + entrypointRegion.println("\t" + fName + "(null);", entrypointUrl, lineNum);// Run it } } @@ -125,8 +142,6 @@ public class DomLessSourceExtractor implements JSSourceExtractor { if (value != null) { // script is out-of-line getScriptFromUrl(value); - } else{ - getInlineScript(tag); } } catch (IOException e) { @@ -148,18 +163,13 @@ public class DomLessSourceExtractor implements JSSourceExtractor { BufferedReader scriptReader = new BufferedReader(new UnicodeReader(scriptInputStream, "UTF8")); while ((line = scriptReader.readLine()) != null) { - scriptRegion.println(line, scriptSrc.getFile(), lineNum++); + scriptRegion.println(line, scriptSrc, lineNum++); } } finally { scriptInputStream.close(); } } - private void getInlineScript(ITag tag) throws IOException { - Pair bodyWithLineNumber = tag.getBodyText(); - scriptRegion.println(bodyWithLineNumber.snd, fileName, bodyWithLineNumber.fst); - } - protected String getScriptName(URL url) throws MalformedURLException { String file = url.getFile(); int lastIdxOfSlash = file.lastIndexOf('/'); @@ -185,10 +195,10 @@ public class DomLessSourceExtractor implements JSSourceExtractor { } } - public Map extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) + public Set extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) throws IOException { - InputStreamReader inputStreamReader = getStream(entrypointUrl); + InputStream inputStreamReader = getStream(entrypointUrl); IGeneratorCallback htmlCallback = createHtmlCallback(entrypointUrl, urlResolver); htmlParser.parse(inputStreamReader, htmlCallback, entrypointUrl.getFile()); @@ -196,18 +206,23 @@ public class DomLessSourceExtractor implements JSSourceExtractor { htmlCallback.writeToFinalRegion(finalRegion); // writing the final region into one SourceFileModule. - File outputFile = createOutputFile(entrypointUrl, DELETE_UPON_EXIT); + File outputFile = createOutputFile(entrypointUrl, DELETE_UPON_EXIT, USE_TEMP_NAME); FileMapping fileMapping = finalRegion.writeToFile(new PrintStream(outputFile)); - SourceFileModule singleFileModule = new SourceFileModule(outputFile, outputFile.getName()); - return Collections.singletonMap(singleFileModule, fileMapping); + MappedSourceModule singleFileModule = new MappedSourceFileModule(outputFile, outputFile.getName(), fileMapping); + return Collections.singleton(singleFileModule); } protected IGeneratorCallback createHtmlCallback(URL entrypointUrl, IUrlResolver urlResolver) { return new HtmlCallback(entrypointUrl, urlResolver); } - private File createOutputFile(URL url, boolean delete) throws IOException { - File outputFile = File.createTempFile(new File(url.getFile()).getName(), ".js"); + private File createOutputFile(URL url, boolean delete, boolean useTempName) throws IOException { + File outputFile; + if (useTempName) { + outputFile = File.createTempFile(new File(url.getFile()).getName(), ".js"); + } else { + outputFile = new File(new File(url.getFile()).getName()); + } if (outputFile.exists()){ outputFile.delete(); } @@ -218,25 +233,25 @@ public class DomLessSourceExtractor implements JSSourceExtractor { } - private InputStreamReader getStream(URL url) throws IOException { + private InputStream getStream(URL url) throws IOException { URLConnection conn = url.openConnection(); conn.setDefaultUseCaches(false); conn.setUseCaches(false); - return new InputStreamReader(conn.getInputStream()); + return conn.getInputStream(); } public static void main(String[] args) throws IOException { // DomLessSourceExtractor domLessScopeGenerator = new DomLessSourceExtractor(); - DomLessSourceExtractor domLessScopeGenerator = new DefaultSourceExtractor(); - domLessScopeGenerator.DELETE_UPON_EXIT = false; + JSSourceExtractor domLessScopeGenerator = new DefaultSourceExtractor(); + JSSourceExtractor.DELETE_UPON_EXIT = false; URL entrypointUrl = new URL(args[0]); IHtmlParser htmlParser = new JerichoHtmlParser(); - IUrlResolver urlResolver = new IdentityUrlResover(); - Map res = domLessScopeGenerator.extractSources(entrypointUrl , htmlParser , urlResolver); - Entry entry = res.entrySet().iterator().next(); - System.out.println(entry.getKey()); - entry.getValue().dump(System.out); + IUrlResolver urlResolver = new IdentityUrlResolver(); + Set res = domLessScopeGenerator.extractSources(entrypointUrl , htmlParser , urlResolver); + MappedSourceModule entry = res.iterator().next(); + System.out.println(entry); + entry.getMapping().dump(System.out); } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/FileMapping.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/FileMapping.java index 760ff82d2..8a94902c7 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/FileMapping.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/FileMapping.java @@ -1,6 +1,17 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.io.PrintStream; +import java.net.URL; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -12,20 +23,20 @@ import com.ibm.wala.util.collections.Pair; * Maps line numbers to lines of other files (fileName + line). */ public class FileMapping{ - protected Map> lineNumberToFileAndLine = HashMapFactory.make(); + protected Map> lineNumberToFileAndLine = HashMapFactory.make(); /** * @param line * @return Null if no mapping for the given line. */ - public Pair getAssociatedFileAndLine(int line){ + public Pair getAssociatedFileAndLine(int line){ return lineNumberToFileAndLine.get(line); } public void dump(PrintStream ps){ Set lines = new TreeSet(lineNumberToFileAndLine.keySet()); for (Integer line : lines){ - Pair fnAndln = lineNumberToFileAndLine.get(line); + Pair fnAndln = lineNumberToFileAndLine.get(line); ps.println(line + ": " + fnAndln.snd + "@" + fnAndln.fst); } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlCallback.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlCallback.java index ae1883dde..bdb57c7dc 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlCallback.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlCallback.java @@ -1,6 +1,17 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; + /** * Callback which is implemented by users of the IHtmlParser. The parser traverses the dom-nodes in an in-order. * @author danielk @@ -11,6 +22,8 @@ public interface IHtmlCallback { void handleStartTag(ITag tag); + void handleText(int lineNumber, String text); + void handleEndTag(ITag tag); - + } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParser.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParser.java index 8c48b1d13..c79647ca1 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParser.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParser.java @@ -1,6 +1,16 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; -import java.io.Reader; +import java.io.InputStream; /** * @author danielk @@ -15,6 +25,6 @@ public interface IHtmlParser { * @param callback * @param fileName */ - public void parse(Reader reader, IHtmlCallback callback, String fileName); + public void parse(InputStream reader, IHtmlCallback callback, String fileName); } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParserFactory.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParserFactory.java new file mode 100644 index 000000000..719c81c9a --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IHtmlParserFactory.java @@ -0,0 +1,7 @@ +package com.ibm.wala.cast.js.html; + +public interface IHtmlParserFactory { + + IHtmlParser getParser(); + +} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/ITag.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/ITag.java index edfb83969..651b9a35b 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/ITag.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/ITag.java @@ -1,9 +1,17 @@ package com.ibm.wala.cast.js.html; +/****************************************************************************** + * Copyright (c) 2002 - 2011 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 + *****************************************************************************/ import java.util.Map; -import com.ibm.wala.util.collections.Pair; - /** * @author danielk * Data structure representing an HTML tag, with its attributes and content. Used by the HTML parser when calling the callback. @@ -24,11 +32,6 @@ public interface ITag { public Map getAllAttributes(); - /** - * @return a pair containing the start line of the tag's body and the actual body as a string - */ - public Pair getBodyText(); - /** * Returns the starting line number of the tag. * @return null if no known diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IUrlResolver.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IUrlResolver.java index 9ad67361f..b6635d7e2 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IUrlResolver.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IUrlResolver.java @@ -1,3 +1,13 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.net.URL; diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResolver.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResolver.java new file mode 100644 index 000000000..b95921755 --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResolver.java @@ -0,0 +1,25 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; + +import java.net.URL; + +public class IdentityUrlResolver implements IUrlResolver{ + + public URL resolve(URL input) { + return input; + } + + public URL deResolve(URL input) { + return input; + } + +} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResover.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResover.java deleted file mode 100644 index 65cd9fbed..000000000 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/IdentityUrlResover.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.ibm.wala.cast.js.html; - -import java.net.URL; - -public class IdentityUrlResover implements IUrlResolver{ - - public URL resolve(URL input) { - return input; - } - - public URL deResolve(URL input) { - return input; - } - -} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/JSSourceExtractor.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/JSSourceExtractor.java index 316223d77..3ef1f5d76 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/JSSourceExtractor.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/JSSourceExtractor.java @@ -1,10 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.io.IOException; import java.net.URL; -import java.util.Map; - -import com.ibm.wala.classLoader.SourceFileModule; +import java.util.Set; /** * Extracts scripts from a given URL of an HTML. Retrieves also attached js files. @@ -13,8 +21,12 @@ import com.ibm.wala.classLoader.SourceFileModule; * @author yinnonh * @author danielk */ -public interface JSSourceExtractor { +public abstract class JSSourceExtractor { - public Map extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) throws IOException; + public static boolean DELETE_UPON_EXIT = true; + + public static boolean USE_TEMP_NAME = true; + + public abstract Set extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) throws IOException; } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceFileModule.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceFileModule.java new file mode 100644 index 000000000..ef1001da2 --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceFileModule.java @@ -0,0 +1,24 @@ +package com.ibm.wala.cast.js.html; + +import java.io.File; + +import com.ibm.wala.classLoader.SourceFileModule; + +public class MappedSourceFileModule extends SourceFileModule implements MappedSourceModule { + private final FileMapping fileMapping; + + public MappedSourceFileModule(File f, String fileName, FileMapping fileMapping) { + super(f, fileName); + this.fileMapping = fileMapping; + } + + public MappedSourceFileModule(File f, SourceFileModule clonedFrom, FileMapping fileMapping) { + super(f, clonedFrom); + this.fileMapping = fileMapping; + } + + public FileMapping getMapping() { + return fileMapping; + } + +} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceModule.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceModule.java new file mode 100644 index 000000000..12e597e5c --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MappedSourceModule.java @@ -0,0 +1,9 @@ +package com.ibm.wala.cast.js.html; + +import com.ibm.wala.classLoader.SourceModule; + +public interface MappedSourceModule extends SourceModule { + + FileMapping getMapping(); + +} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MutableFileMapping.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MutableFileMapping.java index 55902c366..ff471aac1 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MutableFileMapping.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/MutableFileMapping.java @@ -1,11 +1,23 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; +import java.net.URL; + import com.ibm.wala.util.collections.Pair; public class MutableFileMapping extends FileMapping { - void map(int line, String originalFile, int originalLine){ - lineNumberToFileAndLine.put(line, Pair. make(originalFile, originalLine)); + void map(int line, URL originalFile, int originalLine){ + lineNumberToFileAndLine.put(line, Pair. make(originalFile, originalLine)); } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/SourceRegion.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/SourceRegion.java index c5634c64a..1cc36c371 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/SourceRegion.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/SourceRegion.java @@ -1,9 +1,20 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintStream; import java.io.StringReader; +import java.net.URL; import java.util.StringTokenizer; import com.ibm.wala.util.collections.Pair; @@ -17,7 +28,7 @@ public class SourceRegion { public SourceRegion() { } - public void print(String text, String originalFile, int originalLine){ + public void print(String text, URL originalFile, int originalLine){ source.append(text); int numberOfLineDrops = getNumberOfLineDrops(text); if (originalFile != null){ @@ -32,7 +43,7 @@ public class SourceRegion { } } - public void println(String text, String originalFile, int originalLine){ + public void println(String text, URL originalFile, int originalLine){ print(text + "\n", originalFile, originalLine); } @@ -57,7 +68,7 @@ public class SourceRegion { while ((line = br.readLine()) != null){ lineNum++; - Pair fileAndLine = otherRegion.fileMapping.getAssociatedFileAndLine(lineNum); + Pair fileAndLine = otherRegion.fileMapping.getAssociatedFileAndLine(lineNum); if (fileAndLine!= null){ this.println(line, fileAndLine.fst, fileAndLine.snd); } else { @@ -77,7 +88,7 @@ public class SourceRegion { String line = (String) st.nextElement(); lineNum++; - Pair fileAndLine = fileMapping.getAssociatedFileAndLine(lineNum); + Pair fileAndLine = fileMapping.getAssociatedFileAndLine(lineNum); if (fileAndLine!= null){ ps.print(fileAndLine.snd + "@" + fileAndLine.fst + "\t:"); } else { diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UnicodeReader.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UnicodeReader.java index cd6933b69..a13aa4d72 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UnicodeReader.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UnicodeReader.java @@ -1,3 +1,13 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; /** diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UrlManipulator.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UrlManipulator.java index 2c3a33185..f2fb02544 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UrlManipulator.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/UrlManipulator.java @@ -1,3 +1,13 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html; import java.net.MalformedURLException; diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/WebUtil.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/WebUtil.java new file mode 100644 index 000000000..c0383b7a8 --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/WebUtil.java @@ -0,0 +1,61 @@ +/****************************************************************************** + * 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.html; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Set; + +import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser; +import com.ibm.wala.util.debug.Assertions; + +public class WebUtil { + + public static final String preamble = "preamble.js"; + + private static IHtmlParserFactory factory = new IHtmlParserFactory() { + public IHtmlParser getParser() { + return new JerichoHtmlParser(); + } + }; + + public static void setFactory(IHtmlParserFactory factory) { + WebUtil.factory = factory; + } + + public static Set extractScriptFromHTML(String url) { + try { + if (! url.startsWith("file://")) { + url = "file://" + url; + } + return extractScriptFromHTML(new URL(url)); + } catch (MalformedURLException e) { + Assertions.UNREACHABLE( e.toString() ); + return null; + } + } + + public static Set extractScriptFromHTML(URL url) { + try { + JSSourceExtractor extractor = new DefaultSourceExtractor(); + return extractor.extractSources(url, factory.getParser(), new IdentityUrlResolver()); + } catch (IOException e) { + throw new RuntimeException("trouble with " + url, e); + } + } + + public static void main(String[] args) throws MalformedURLException { + System.err.println(extractScriptFromHTML(new URL(args[0]))); + } +} + + diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoHtmlParser.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoHtmlParser.java index 7a8062cf3..57a5cef79 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoHtmlParser.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoHtmlParser.java @@ -1,14 +1,25 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html.jericho; import java.io.IOException; -import java.io.Reader; +import java.io.InputStream; import java.util.Iterator; import java.util.List; -import au.id.jericho.lib.html.Config; -import au.id.jericho.lib.html.Element; -import au.id.jericho.lib.html.LoggerProvider; -import au.id.jericho.lib.html.Source; +import net.htmlparser.jericho.Config; +import net.htmlparser.jericho.Element; +import net.htmlparser.jericho.LoggerProvider; +import net.htmlparser.jericho.Source; + import com.ibm.wala.cast.js.html.IHtmlCallback; import com.ibm.wala.cast.js.html.IHtmlParser; @@ -23,8 +34,7 @@ public class JerichoHtmlParser implements IHtmlParser{ Config.LoggerProvider = LoggerProvider.STDERR; } - @SuppressWarnings("unchecked") - public void parse(Reader reader, IHtmlCallback callback, String fileName) { + public void parse(InputStream reader, IHtmlCallback callback, String fileName) { Parser parser = new Parser(callback, fileName); Source src; try { @@ -51,10 +61,10 @@ public class JerichoHtmlParser implements IHtmlParser{ this.fileName = fileName; } - @SuppressWarnings("unchecked") private void parse(Element root) { JerichoTag tag = new JerichoTag(root, fileName); handler.handleStartTag(tag); + handler.handleText(tag.getStartingLineNum(), tag.getBodyText().snd); List childElements = root.getChildElements(); for (Iterator nodeIterator = childElements.iterator(); nodeIterator.hasNext();) { Element child = nodeIterator.next(); diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoTag.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoTag.java index 49344e010..a3d75247a 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoTag.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/jericho/JerichoTag.java @@ -1,10 +1,21 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html.jericho; import java.util.Map; -import au.id.jericho.lib.html.Attributes; -import au.id.jericho.lib.html.Element; -import au.id.jericho.lib.html.Segment; +import net.htmlparser.jericho.Attributes; +import net.htmlparser.jericho.Element; +import net.htmlparser.jericho.Segment; + import com.ibm.wala.cast.js.html.ITag; import com.ibm.wala.util.collections.HashMapFactory; @@ -20,13 +31,12 @@ public class JerichoTag implements ITag { private final String sourceFile; private Map attributesMap; - @SuppressWarnings("unchecked") public JerichoTag(Element root, String sourceFile) { this.innerElement = root; Attributes attributes = innerElement.getStartTag().getAttributes(); attributesMap = HashMapFactory.make(); if (attributes != null) { - attributesMap = attributes.populateMap(attributesMap, false); + attributesMap = attributes.populateMap(attributesMap, true); } this.sourceFile = sourceFile; } @@ -36,7 +46,7 @@ public class JerichoTag implements ITag { } public String getAttributeByName(String name) { - return attributesMap.get(name); + return attributesMap.get(name.toLowerCase()); } public Pair getBodyText() { diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/nu_validator/NuValidatorHtmlParser.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/nu_validator/NuValidatorHtmlParser.java new file mode 100644 index 000000000..0a7749a96 --- /dev/null +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/nu_validator/NuValidatorHtmlParser.java @@ -0,0 +1,164 @@ +/****************************************************************************** + * Copyright (c) 2002 - 2011 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.html.nu_validator; + +import java.io.IOException; +import java.io.InputStream; +import java.io.LineNumberReader; +import java.io.StringReader; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import nu.validator.htmlparser.common.XmlViolationPolicy; +import nu.validator.htmlparser.sax.HtmlParser; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +import com.ibm.wala.cast.js.html.IHtmlCallback; +import com.ibm.wala.cast.js.html.IHtmlParser; +import com.ibm.wala.cast.js.html.ITag; + +public class NuValidatorHtmlParser implements IHtmlParser { + + public void parse(final InputStream reader, final IHtmlCallback handler, String fileName) { + HtmlParser parser = new HtmlParser(); + parser.setXmlPolicy(XmlViolationPolicy.ALLOW); + parser.setContentHandler(new ContentHandler() { + private Locator locator; + private Stack tags = new Stack();; + + private int countLines(char[] ch, int start, int length) { + LineNumberReader r = new LineNumberReader(new StringReader (new String(ch, start, length))); + try { + while (r.read() > -1); + } catch (IOException e) { + throw new RuntimeException("cannot read from string", e); + } + return r.getLineNumber(); + } + + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + public void startElement(String uri, final String localName, String qName, final Attributes atts) throws SAXException { + final int line = locator.getLineNumber(); + tags.push(new ITag() { + + public String getName() { + return localName; + } + + public String getAttributeByName(String name) { + return atts.getValue(name); + } + + public Map getAllAttributes() { + return new AbstractMap() { + private Set> es = null; + + @Override + public Set> entrySet() { + if (es == null) { + es = new HashSet>(); + for(int i = 0; i < atts.getLength(); i++) { + final int index = i; + es.add(new Map.Entry() { + + public String getKey() { + return atts.getLocalName(index); + } + + public String getValue() { + return atts.getValue(index); + } + + public String setValue(String value) { + throw new UnsupportedOperationException(); + } + }); + } + } + return es; + } + }; + } + + public int getStartingLineNum() { + return line; + } + }); + handler.handleStartTag(tags.peek()); + } + + public void endElement(String uri, String localName, String qName) throws SAXException { + handler.handleEndTag(tags.pop()); + } + + public void characters(char[] ch, int start, int length) throws SAXException { + handler.handleText(locator.getLineNumber() - countLines(ch, start, length), new String(ch, start, length)); + } + + public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { + handler.handleText(locator.getLineNumber(), new String(ch, start, length)); + } + + public void startDocument() throws SAXException { + // do nothing + } + + public void endDocument() throws SAXException { + // do nothing + } + + public void startPrefixMapping(String prefix, String uri) throws SAXException { + // do nothing + } + + public void endPrefixMapping(String prefix) throws SAXException { + // do nothing + } + + public void processingInstruction(String target, String data) throws SAXException { + // do nothing + } + + public void skippedEntity(String name) throws SAXException { + // do nothing + } + + }); + + try { + parser.parse(new InputSource(new InputStream() { + @Override + public int read() throws IOException { + int v; + do { + v = reader.read(); + } while (v == '\r'); + return v; + } + })); + } catch (IOException e) { + assert false : e.toString(); + } catch (SAXException e) { + assert false : e.toString(); + } + } +} diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSCFABuilder.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSCFABuilder.java index 402e193c3..8d8a5fdec 100755 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSCFABuilder.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSCFABuilder.java @@ -14,9 +14,11 @@ import java.util.Iterator; import com.ibm.wala.cast.ipa.callgraph.AstCFAPointerKeys; import com.ibm.wala.cast.js.types.JavaScriptTypes; +import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.IField; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey; import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; import com.ibm.wala.ipa.callgraph.propagation.PointerKey; import com.ibm.wala.ipa.cha.IClassHierarchy; @@ -65,8 +67,12 @@ public class JSCFABuilder extends JSSSAPropagationCallGraphBuilder { @Override public Iterator getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) { + IClassHierarchy cha = I.getConcreteType().getClassHierarchy(); + IClass function = cha.lookupClass(JavaScriptTypes.Function); if (isBogusKey(I)) { return EmptyIterator.instance(); + } else if (cha.isSubclassOf(F.getConcreteType(), function)) { + return super.getPointerKeysForReflectedFieldRead(I, new ConcreteTypeKey(function)); } else { return super.getPointerKeysForReflectedFieldRead(I, F); } @@ -74,12 +80,17 @@ public class JSCFABuilder extends JSSSAPropagationCallGraphBuilder { @Override public Iterator getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) { + IClassHierarchy cha = I.getConcreteType().getClassHierarchy(); + IClass function = cha.lookupClass(JavaScriptTypes.Function); if (isBogusKey(I)) { return EmptyIterator.instance(); + } else if (cha.isSubclassOf(F.getConcreteType(), function)) { + return super.getPointerKeysForReflectedFieldWrite(I, new ConcreteTypeKey(function)); } else { return super.getPointerKeysForReflectedFieldWrite(I, F); } } + }); } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSSSAPropagationCallGraphBuilder.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSSSAPropagationCallGraphBuilder.java index 6792d9165..de5b50844 100755 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSSSAPropagationCallGraphBuilder.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSSSAPropagationCallGraphBuilder.java @@ -11,7 +11,11 @@ package com.ibm.wala.cast.js.ipa.callgraph; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import com.ibm.wala.analysis.typeInference.TypeInference; import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder; @@ -59,6 +63,7 @@ import com.ibm.wala.ssa.SSABinaryOpInstruction; import com.ibm.wala.ssa.SSAUnaryOpInstruction; import com.ibm.wala.ssa.SymbolTable; import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.collections.Pair; import com.ibm.wala.util.intset.IntSetAction; import com.ibm.wala.util.intset.IntSetUtil; import com.ibm.wala.util.intset.MutableIntSet; @@ -70,12 +75,43 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph public static final boolean DEBUG_TYPE_INFERENCE = false; - URL scriptBaseURL; + private URL scriptBaseURL; + + public URL getBaseURL() { + return scriptBaseURL; + } public void setBaseURL(URL url) { this.scriptBaseURL = url; } + private SortedMap scriptIndexToFragment; + private Map scriptFragmentToLine; + + public void setFragments(SortedMap map) { + int i = 0; + scriptIndexToFragment = new TreeMap(); + for(Map.Entry e : map.entrySet()) { + scriptIndexToFragment.put(i++, e.getValue()); + } + scriptFragmentToLine = new HashMap(map.size()); + for(Map.Entry e : map.entrySet()) { + scriptFragmentToLine.put(e.getValue().toString(), e.getKey()); + } + } + + public URL getFragment(int i) { + return scriptIndexToFragment.get(i); + } + + public Pair mapPosition(URL fragment, int line) { + if (fragment.toString().indexOf("scriptTag") < 0) { + return Pair.make(fragment, line); + } else { + return Pair.make(scriptBaseURL, scriptFragmentToLine.get(fragment) + line); + } + } + protected JSSSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, PointerKeyFactory pointerKeyFactory) { super(cha, options, cache, pointerKeyFactory); diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/LoadFileTargetSelector.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/LoadFileTargetSelector.java index fc6416f70..1fd402d5d 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/LoadFileTargetSelector.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/LoadFileTargetSelector.java @@ -55,7 +55,7 @@ public class LoadFileTargetSelector implements MethodTargetSelector { String str = names.iterator().next(); try { JavaScriptLoader cl = (JavaScriptLoader) builder.getClassHierarchy().getLoader(JavaScriptTypes.jsLoader); - URL url = new URL(builder.scriptBaseURL, str); + URL url = new URL(builder.getBaseURL(), str); Util.loadAdditionalFile(builder.getClassHierarchy() , cl, str, url, url.getFile()); IClass script = builder.getClassHierarchy().lookupClass(TypeReference.findOrCreate(cl.getReference(), "L" + url.getFile())); return script.getMethod(JavaScriptMethods.fnSelector); @@ -63,6 +63,8 @@ public class LoadFileTargetSelector implements MethodTargetSelector { // do nothing, fall through and return 'target' } catch (IOException e) { // do nothing, fall through and return 'target' + } catch (RuntimeException e) { + // do nothing, fall through and return 'target' } } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/Util.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/Util.java index fc42c051d..6f56e420f 100755 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/Util.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/Util.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.net.URL; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -122,34 +123,38 @@ public class Util extends com.ibm.wala.cast.ipa.callgraph.Util { * @throws IOException */ public static Set loadAdditionalFile(IClassHierarchy cha, JavaScriptLoader cl, String fileName, URL url, String file) throws IOException { - SourceURLModule M = new SourceURLModule(url); - TranslatorToCAst toCAst = getTranslatorFactory().make(new CAstImpl(), M, url, file); - final Set names = new HashSet(); - JSAstTranslator toIR = new JSAstTranslator(cl) { - protected void defineFunction(CAstEntity N, - WalkContext definingContext, - AbstractCFG cfg, - SymbolTable symtab, - boolean hasCatchBlock, - TypeReference[][] caughtTypes, - boolean hasMonitorOp, - AstLexicalInformation LI, - DebuggingInformation debugInfo) - { - String fnName = "L" + composeEntityName(definingContext, N); - names.add(fnName); - super.defineFunction(N, definingContext, cfg, symtab, hasCatchBlock, caughtTypes, hasMonitorOp, LI, debugInfo); + try{ + SourceURLModule M = new SourceURLModule(url); + TranslatorToCAst toCAst = getTranslatorFactory().make(new CAstImpl(), M); + final Set names = new HashSet(); + JSAstTranslator toIR = new JSAstTranslator(cl) { + protected void defineFunction(CAstEntity N, + WalkContext definingContext, + AbstractCFG cfg, + SymbolTable symtab, + boolean hasCatchBlock, + TypeReference[][] caughtTypes, + boolean hasMonitorOp, + AstLexicalInformation LI, + DebuggingInformation debugInfo) + { + String fnName = "L" + composeEntityName(definingContext, N); + names.add(fnName); + super.defineFunction(N, definingContext, cfg, symtab, hasCatchBlock, caughtTypes, hasMonitorOp, LI, debugInfo); + } + }; + CAstEntity tree = toCAst.translateToCAst(); + if (DEBUG){ + CAstPrinter.printTo(tree, new PrintWriter(System.err)); } - }; - CAstEntity tree = toCAst.translateToCAst(); - if (DEBUG){ - CAstPrinter.printTo(tree, new PrintWriter(System.err)); + toIR.translate(tree, fileName); + for(String name : names) { + IClass fcls = cl.lookupClass(name, cha); + cha.addClass(fcls); + } + return names; + } catch (RuntimeException e) { + return Collections.emptySet(); } - toIR.translate(tree, fileName); - for(String name : names) { - IClass fcls = cl.lookupClass(name, cha); - cha.addClass(fcls); - } - return names; } } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java index 01e94ce98..8038bf928 100755 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java @@ -11,7 +11,6 @@ package com.ibm.wala.cast.js.loader; import java.io.UnsupportedEncodingException; -import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -70,6 +69,7 @@ import com.ibm.wala.classLoader.LanguageImpl; import com.ibm.wala.classLoader.Module; import com.ibm.wala.classLoader.ModuleEntry; import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.classLoader.SourceModule; import com.ibm.wala.classLoader.SourceURLModule; import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.shrikeBT.IBinaryOpInstruction.IOperator; @@ -844,8 +844,8 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader { } @Override - protected TranslatorToCAst getTranslatorToCAst(CAst ast, ModuleEntry module, URL sourceURL, String localFileName) { - return translatorFactory.make(ast, module, sourceURL, localFileName); + protected TranslatorToCAst getTranslatorToCAst(CAst ast, SourceModule module) { + return translatorFactory.make(ast, module); } @Override diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JSAstTranslator.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JSAstTranslator.java index 07dee3fe4..866ac3ef4 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JSAstTranslator.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JSAstTranslator.java @@ -97,8 +97,9 @@ public class JSAstTranslator extends AstTranslator { return readVn; } - protected void defineType(CAstEntity type, WalkContext wc) { + protected boolean defineType(CAstEntity type, WalkContext wc) { Assertions.UNREACHABLE("JavaScript doesn't have types. I suggest you look elsewhere for your amusement."); + return false; } protected void defineField(CAstEntity topEntity, WalkContext wc, CAstEntity n) { @@ -140,6 +141,7 @@ public class JSAstTranslator extends AstTranslator { if (DEBUG) System.err.println(cfg); + symtab.getNullConstant(); symtab.getConstant("arguments"); symtab.getConstant("length"); for(int i = 0; i < 20; i++) { diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JavaScriptTranslatorFactory.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JavaScriptTranslatorFactory.java index 90b580e74..ba5d0368c 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JavaScriptTranslatorFactory.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/translator/JavaScriptTranslatorFactory.java @@ -10,14 +10,12 @@ *****************************************************************************/ package com.ibm.wala.cast.js.translator; -import java.net.URL; - import com.ibm.wala.cast.ir.translator.TranslatorToCAst; import com.ibm.wala.cast.tree.CAst; -import com.ibm.wala.classLoader.ModuleEntry; +import com.ibm.wala.classLoader.SourceModule; public interface JavaScriptTranslatorFactory { - TranslatorToCAst make(CAst ast, ModuleEntry M, URL sourceURL, String localFileName); + TranslatorToCAst make(CAst ast, SourceModule M); }