@Test public void testComplexStack() { try { eval( "", "var x = { one: function() { bar() } };", "var y = { two: x.one };", "function foo() {", " throw TypeError();", "}", "function bar() {", " foo();", "}", "", "try {", " (function(){y.two();})();", "} catch(e) {", " print(e.stack);", " throw e;", "}"); throw new AssertionError("Should have thrown"); } catch (ThrowException e) { JSObject o = (JSObject) e.getValue(); String stack = (String) o.get(getContext(), "stack"); assertThat(stack.contains("TypeError\n")).isTrue(); assertThat(stack.contains("at foo (<eval>:5)")).isTrue(); assertThat(stack.contains("at bar (<eval>:8)")).isTrue(); assertThat(stack.contains("at Object.one (<eval>:2)")).isTrue(); assertThat(stack.contains("at <anonymous> (<eval>:12)")).isTrue(); assertThat(stack.contains("at <eval> (<eval>:12)")).isTrue(); } }
private boolean isDummy(Location obj) { JSObject heapObj = this.get(obj); if (heapObj == null) return false; ObjectValue val = heapObj.get("at_Dummy"); if (val != null) return true; else return false; }
private static String _getString(String name, JSObject... places) { for (JSObject o : places) { if (o == null) continue; Object temp = o.get(name); if (temp == null) continue; return temp.toString(); } return null; }
/** * Prototype Lookup * * @param currentLoc * @param property_name * @return null if the prototype chain leads to null when looking for the property or a location * if the object at that location contains the property */ public Location Prototype(Location currentLoc, String property_name) { if (currentLoc != null) { JSObject obj = this.get(currentLoc); if (obj != null) { if (obj.isin(property_name)) return currentLoc; else { Location proto = (Location) obj.get("__proto__"); return Prototype(proto, property_name); } } } return null; }
/** * Returns a property within this object. * * @param path Property names separated by dots ('.') * @return The string representation of the requested property or <strong>null</strong>, if it * doesn't exist */ public String access(String path) { JSObject current = this; String[] nodes = (path != null) ? path.split("\\.") : new String[0]; for (int i = 0; i < nodes.length; i++) { if (current != null) { current = current.get(nodes[i]); } else { break; } } return (current == null) ? null : current.toString(); }
/** * Returns the scope object enclosing the desired property * * @param currentLoc * @param property_name * @return */ public Location Scope(Location currentLoc, String property_name) { if (currentLoc == null) return null; if (this.hasProperty( currentLoc, property_name)) // Check if the prototype chain has the property return currentLoc; else { // if not, then check if the scope chain has the property JSObject obj = this.get(currentLoc); if (obj != null) { Location sc = (Location) obj.get("at_Scope"); return Scope(sc, property_name); } else { return null; } } }
/** * updates the context to the correct branch based on environment and to the latest version of the * code if name or environemnt is missing, does nothing */ public String updateCode() { if (!_git.isValid()) throw new RuntimeException(_rootFile + " is not a git repository"); _logger.info("going to update code"); _git.fullUpdate(); if (_name == null || _environment == null) return getCurrentGitBranch(); JSObject env = getEnvironmentObject(); if (env == null) return null; String branch = env.get("branch").toString(); _logger.info("updating to [" + branch + "]"); _git.checkout(branch); Python.deleteCachedJythonFiles(_rootFile); return getCurrentGitBranch(true); }
@Test public void testDeleteOper() { check("var x = {a:'lol'}; var result = delete x.a;", true); JSObject x = (JSObject) getContext().resolve("x").getValue(getContext()); assertThat(x.get(getContext(), "a")).isEqualTo(Types.UNDEFINED); }
/** * Displays the heap so that it can be visualized as a graph * * @return */ public String toGraphRep() { Location global = this.getGlobal(); String graphviz = "digraph G{"; Set<Location> locs = heap.keySet(); for (Location l : locs) { JSObject lj = heap.get(l); if (l == global) { graphviz += l.getObjValue() + "[ fillcolor = \"green\", style = \"filled\"];"; } if (lj.isin("at_Taint")) { if (lj.get("at_Taint") != null) { if (((SecurityType) lj.get("at_Taint")).isTainted()) { graphviz += l.getObjValue() + "[ fillcolor = \"red\", style = \"filled\"];"; } else { graphviz += l.getObjValue() + "[ fillcolor = \"lightblue\", style = \"filled\"];"; } } } Set<String> keys = lj.getKeySet(); for (String key : keys) { ObjectValue ov = lj.get(key); if (ov != null) { if (ov instanceof Location) { if (key.equals("innerHTML")) { graphviz += ov.getObjValue() + "[ fillcolor = \"lightblue\", style = \"filled\"];"; } JSObject jsov = heap.get(ov); if (jsov != null) { if (jsov.isin("at_Taint")) { if (jsov.get("at_Taint") != null) { if (((SecurityType) jsov.get("at_Taint")).isTainted()) { graphviz += ov.getObjValue() + "[ fillcolor = \"red\", style = \"filled\"];"; } else { graphviz += ov.getObjValue() + "[ fillcolor = \"lightblue\", style = \"filled\"];"; } } } } String key_new = key; if (key.endsWith("\"")) { key_new = key.substring(1, key.length() - 1); key = key_new; } // if(!key_new.equals("at_Class") && !key_new.equals("__constructor__") && // !key_new.equals("at_FScope") && !key_new.equals("at_Scope") ){ graphviz += "\n" + l.getObjValue() + " -> " + ov.getObjValue() + " [ label = \"" + key_new + "\" ];"; // } } } } } graphviz += "}"; return graphviz; }
/** * Recursive function to check if the JSObjects in both the heaps match * * @param other * @param this_global * @param other_global * @return */ private boolean checkContentEquality(Heap other, Location this_obj, Location other_obj) { JSObject curr_obj = this.get(this_obj); JSObject test_obj = other.get(other_obj); if (curr_obj == null && test_obj == null) return true; if ((curr_obj != null && test_obj == null) || (curr_obj == null && test_obj != null)) return false; SecurityType curr_taint = (SecurityType) curr_obj.get("at_Taint"); SecurityType test_taint = (SecurityType) test_obj.get("at_Taint"); // Proceed further only if the JSObject taints match if (curr_taint.equals(test_taint)) { // If the location is a dummy object, it suffices to just check the taints if (other.isDummy(other_obj) && this.isDummy(this_obj)) { return true; } Set<String> this_keyset = curr_obj.getKeySet(); Set<String> other_keyset = test_obj.getKeySet(); // Proceed further only if the keys in both the JSObjects match if (this_keyset.containsAll(other_keyset) && other_keyset.containsAll(this_keyset)) { // For each key compare the object values boolean retval = true; for (String key : this_keyset) { // we don't want to go into libraryProperties as they will lead to the parents // creating a circular check and infinite recursion if (ProgramAnalyzerC.libraryProperties.contains(key)) continue; if (key.equals("at_Taint")) // we already compared taints continue; ObjectValue this_val = curr_obj.get(key); ObjectValue other_val = test_obj.get(key); if (this_val == null && other_val == null) { continue; } if ((this_val == null && other_val != null) || (this_val != null && other_val == null)) { retval = false; return retval; } if (this_val.getClass() != other_val.getClass()) { retval = false; // If the class types don't match return retval; } if (this_val instanceof Location) retval = retval && checkContentEquality(other, (Location) this_val, (Location) other_val); if (this_val instanceof FunctionValue) retval = retval && ((FunctionValue) this_val).equals((FunctionValue) other_val); if (this_val instanceof ObjectValue) retval = retval && this_val.equals(other_val); if (retval == false) return false; } return retval; } } return false; }
private void _loadConfigFromCloudObject(JSObject o) { if (o == null) return; _configScope.putAll((JSObject) o.get("config")); }