dojo-release-1.7.2-shrinksafe/ 0000755 0002154 0303237 00000000000 11717260147 016332 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/LICENSE 0000644 0002154 0303237 00000000504 11717260147 017336 0 ustar csnover allusers Mozilla Rhino (js.jar from http://www.mozilla.org/rhino/) was initially developed by Netscape Communications Corporation and is provided by the Dojo Foundation "as is" under the MPL 1.1 license, available at http://www.mozilla.org/MPL shrinksafe.jar is based on work in Rhino and is also provided under the MPL 1.1 license. dojo-release-1.7.2-shrinksafe/tests/ 0000755 0002154 0303237 00000000000 11717260147 017474 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/tests/9444.js 0000644 0002154 0303237 00000000231 11717260147 020432 0 ustar csnover allusers (function(){ var someComplicatedStuff = function(){ debugger; } for(var i = 0; i < 10; i++){ if(i % 2 === 0) someComplicatedStuff(); } })() dojo-release-1.7.2-shrinksafe/tests/stripconsole.js 0000644 0002154 0303237 00000001576 11717260147 022567 0 ustar csnover allusers result = ""; /* For the purpose of these tests, we have no actual console with which to test output, so create a dummy console and capture to 'result', which is examined by the test framework post eval. */ var console = { debug: function(arg) { result += "DEBUG: " + arg; }, warn: function(arg) { result += "WARN: " + arg; }, error: function(arg) { result += "ERROR: " + arg; }, dir: function(arg) { result += "DIR: " + arg; } }; /* Make something that looks a bit like console to ensure it isn't stripped. */ var notconsole = { debug: function(arg) { result += arg; }, warn: function(arg) { result += arg; } }; (function() { var variable = 'variable'; console.debug("debug here!" + variable); console.warn("warn here!"); console.error("error here!"); notconsole.debug("notconsole debug here!"); notconsole.warn("notconsole warn here!"); console.dir(notconsole); })(); dojo-release-1.7.2-shrinksafe/tests/1768.js 0000644 0002154 0303237 00000000352 11717260147 020437 0 ustar csnover allusers // testing a simple var list with embedded things. var result = 0; (function(){ var a = 2, b = 3, superLong = 4, aFunction = function(arg){ var inList = superLong; result = inList; } ; aFunction(superLong); })(); dojo-release-1.7.2-shrinksafe/tests/module.js 0000644 0002154 0303237 00000015732 11717260147 021327 0 ustar csnover allusers dojo.provide("shrinksafe.tests.module"); // basic helper functions for running multiple tests. shrinksafe.tests.module.getContents = function(path){ // summary: Load a file from this /tests/ path into a variable path = "../shrinksafe/tests/" + path; return readFile(path); // String } shrinksafe.tests.module.compress = function(source, stripConsole, escapeUnicode){ // summary: Shorthand to compress some String version of JS code return new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(source, 0, 1, escapeUnicode, stripConsole)).toString(); } shrinksafe.tests.module.loader = function(path, stripConsole, escapeUnicode){ // summary: Simple function to load and compress some file. Returns and object // with 'original' and 'compressed' members, respectively. var s = shrinksafe.tests.module.getContents(path); return { original: s, compressed: shrinksafe.tests.module.compress(s, stripConsole, escapeUnicode || false) }; } try{ tests.register("shrinksafe", [ function forwardReference(t){ var src = shrinksafe.tests.module.loader("3241.js", null); t.assertTrue(src.original.length > src.compressed.length); t.assertTrue(src.compressed.indexOf("test") == -1) eval(src.compressed); t.assertEqual("data", result); delete result; }, function nestedReference(t){ var src = shrinksafe.tests.module.loader("5303.js", null); t.assertTrue(src.original.length > src.compressed.length); t.assertTrue(src.compressed.indexOf("say_hello") == -1) t.assertTrue(src.compressed.indexOf("callback") == -1) eval(src.compressed); // make sure it runs to completion t.assertEqual("hello worldhello world", result); // globals must not be renamed t.assertEqual("function", typeof CallMe); delete result; }, function varConflict(t){ // ensuring a shrunken variable won't overwrite an existing variable // name, regardless of scope. var src = shrinksafe.tests.module.loader("8974.js", null); t.assertTrue(src.original.length > src.compressed.length); t.assertTrue(src.compressed.indexOf("variabletwo") == -1) eval(src.compressed); t.assertEqual(-1, result); delete result; }, function varlists(t){ // test to ensure var a, b, c; always works var src = shrinksafe.tests.module.loader("1768.js", null); // ensure the things we expect to hide are hidden t.t(src.compressed.indexOf("superlong") == -1); t.t(src.compressed.indexOf("aFunction") == -1); t.t(src.compressed.indexOf("inList") == -1); // sanity checking: var boo = eval(src.compressed); t.is(4, result); delete result; }, function stripConsoleNormal(t){ var src = shrinksafe.tests.module.loader("stripconsole.js", "normal"); t.assertTrue(src.compressed.indexOf("console.debug(\"debug here!\"") == -1) t.assertTrue(src.compressed.indexOf("console.warn(\"warn here!\")") != -1) t.assertTrue(src.compressed.indexOf("console.error(\"error here!\")") != -1) eval(src.compressed); // make sure expected output occurs. t.assertEqual("WARN: warn here!ERROR: error here!notconsole debug here!notconsole warn here!", result); delete result; }, function stripConsoleWarns(t){ var src = shrinksafe.tests.module.loader("stripconsole.js", "warn"); t.assertTrue(src.original.length > src.compressed.length); t.assertTrue(src.compressed.indexOf("console.debug(\"debug here!\"") == -1) t.assertTrue(src.compressed.indexOf("console.warn(\"warn here!\")") == -1) t.assertTrue(src.compressed.indexOf("console.error(\"error here!\")") != -1) eval(src.compressed); // make sure expected output occurs. t.assertEqual("ERROR: error here!notconsole debug here!notconsole warn here!", result); delete result; }, function stripConsoleAll(t){ var src = shrinksafe.tests.module.loader("stripconsole.js", "all"); t.assertTrue(src.original.length > src.compressed.length); t.assertTrue(src.compressed.indexOf("console.debug(\"debug here!\"") == -1) t.assertTrue(src.compressed.indexOf("console.warn(\"warn here!\")") == -1) t.assertTrue(src.compressed.indexOf("console.error(\"error here!\")") == -1) eval(src.compressed); // make sure expected output occurs. t.assertEqual("notconsole debug here!notconsole warn here!", result); delete result; }, function stripConsoleComplex(t){ var src = shrinksafe.tests.module.loader("stripcomplex.js", "normal"); t.assertTrue(src.original.length > src.compressed.length); eval(src.compressed); // make sure expected output occurs. t.assertEqual("ERROR: wooosome \\ dodgy \" characters *$!?//3-3fn saw arg 'wooo'.ERROR: Error return statement.", result); delete result; }, function debuggerCall(t){ // make sure we don't die when we find a debugger; statement var src = shrinksafe.tests.module.loader("9444.js", null); t.t(src.compressed.indexOf("debugger") > -1); }, function nestedReference(t){ var src = shrinksafe.tests.module.loader("9676.js", null); eval(src.compressed); // will throw on failure t.assertEqual(6, result); delete result; }, function escapeUnicode(t){ var src = shrinksafe.tests.module.loader("escapeunicode.js", null); t.assertTrue(src.compressed.indexOf('"\u03b1";') == 0); // t.is('"\u03b1 \u03c9";', src.compressed); // extended test isn't working... encoding problem with input? src = shrinksafe.tests.module.loader("escapeunicode.js", null, true); t.assertTrue(src.compressed.indexOf('"\\u03b1";') == 0); // t.is('"\\u03b1 \\u03c9";', src.compressed); }, function mungeStrings(t){ // this test is skipped intentionally. You must manually enabled the // code in Compressor.java which enables this functionality. The functionality // is not considered completely "safe" and thus has been disabled. // simply uncomment the block in Compressor.java to reinstate functionality. // original patch came under [ccla]. See bugs.dojotoolkit.org/ticket/8828 return; var src = shrinksafe.tests.module.loader("8828.js"); t.t(src.compressed.indexOf("ab") > -1); // basic test t.t(src.compressed.indexOf('"a"+n') > -1); // basic expected miss t.t(src.compressed.indexOf('thisisatestspanning"+h') > -1); t.t(src.compressed.indexOf("testingmultiplelines") > -1); t.t(src.compressed.indexOf("testingcombined\"+") > -1); var boo = eval(src.compressed); t.is(5, result.length); t.t(result[3].indexOf("TheQuickredFox") > -1); // complex var post eval t.is(result[4], "thisisatestspanning4lines"); // multiline post eval delete result; var expected = [ "testing","testbarsimple", "testingcombinedbarvariables", "test \"+weird syntax", "testbasic", "test \"mixed\"", "testingmultiplelines", "test \"mixed\" andmunge", "test", "tesbart", "\"slightly\"+\"off\"", // fails: "falseb", "falseb", "falseb" ]; var data = string_tests(); data.forEach(function(str, i){ t.is(expected[i], str); }); delete string_tests; } ]); }catch(e){ doh.debug(e); } dojo-release-1.7.2-shrinksafe/tests/escapeunicode.js 0000644 0002154 0303237 00000000021 11717260147 022632 0 ustar csnover allusers "\u03B1";//+" ω" dojo-release-1.7.2-shrinksafe/tests/runner.sh 0000755 0002154 0303237 00000000325 11717260147 021344 0 ustar csnover allusers #!/bin/sh cd ../../doh java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main runner.js testModule=shrinksafe.tests.module testUrl=../shrinksafe/tests/module.js dojo-release-1.7.2-shrinksafe/tests/3241.js 0000644 0002154 0303237 00000000354 11717260147 020425 0 ustar csnover allusers result = ""; (function() { function MyClass(){ this.foo = function(argument1, argument2){ var mytest = test; return mytest; } this.bar = function(){} } var test = "data"; result = new MyClass().foo(); })(); dojo-release-1.7.2-shrinksafe/tests/8828.js 0000644 0002154 0303237 00000001652 11717260147 020447 0 ustar csnover allusers var result = [], string_tests; (function(){ // testing string munging var n = "c"; result.push("a" + "b", "a" + n); var ll = "+"; result.push(ll); var color = "red"; var f = "The" + "Quick" + color + "Fox"; result.push(f); var h = 4; var multiline = "this" + "is" + "a" + "test" + "spanning" + h + "lines" ; result.push(multiline); // aliases. all "bar" var a = "bar", b = 'bar', c = a; // a multi-line string outside of the array var ml = "testing" + "multiple" + "lines"; var val = [ "test" + "ing", "test" + a + "simple", "testing" + "combined" + b + "variables", "test \"+" + "weird syntax", 'test' + 'basic', 'test "mixed"', ml, 'test "mixed" and' + 'munge', "t" + "e" + "s" + "t", "t" + "e" + "s" + c + "t", // weirdest example imaginable?: '"slightly"+"off"', // fail: !"a" + "b", (!"a") + "b", !("a") + "b" ]; string_tests = function(){ return val; } })(); dojo-release-1.7.2-shrinksafe/tests/stripcomplex.js 0000644 0002154 0303237 00000002431 11717260147 022563 0 ustar csnover allusers result = ""; /* For the purpose of these tests, we have no actual console with which to test output, so create a dummy console and capture to 'result', which is examined by the test framework post eval. */ var console = { log: function(arg) { result += "LOG: " + arg; }, debug: function(arg) { result += "DEBUG: " + arg; }, warn: function(arg) { result += "WARN: " + arg; }, error: function(arg) { result += "ERROR: " + arg; }, dir: function(arg) { result += "DIR: " + arg; } }; (function() { var fn = function(arg) { return "fn saw arg '" + arg + "'."; } var str = "wooo"; console.debug(str + "some \\ dodgy \" characters *$!?//" + (1+2) + (~2) + fn(str)); console.error(str + "some \\ dodgy \" characters *$!?//" + (1+2) + (~2) + fn(str)); // from ticket http://bugs.dojotoolkit.org/ticket/8549 console.log("hello :) world!"); console.log(" anything /) with a paren "); console.log(/^\)$/.test("hi")); //It would be interesting to see how this comes out: if(true) console.log("foo"); else var two = "two"; var bar; true ? console.log("bizarre") : (bar = true); true ? (bar = true) : console.log("bizarre"); (function() { return console.debug("Debug return statement."); })(); (function() { return console.error("Error return statement."); })(); })(); dojo-release-1.7.2-shrinksafe/tests/5303.js 0000644 0002154 0303237 00000000506 11717260147 020425 0 ustar csnover allusers result = ""; (function() { CallMe = function(callback) { callback(); }; var say_hello_twice = function() { say_hello(); CallMe(function(){ say_hello(); }); }; var say_hello = function() { result += 'hello world'; }; say_hello_twice(); })(); dojo-release-1.7.2-shrinksafe/tests/8974.js 0000644 0002154 0303237 00000000175 11717260147 020450 0 ustar csnover allusers result = ""; (function() { var _3 = -1; var variableone = 1, variabletwo = 2, variable3 = 3; result = _3; })(); dojo-release-1.7.2-shrinksafe/tests/9676.js 0000644 0002154 0303237 00000000107 11717260147 020443 0 ustar csnover allusers // make sure plus and pos don't become inc. var result = 1 + +2 - -3; dojo-release-1.7.2-shrinksafe/src/ 0000755 0002154 0303237 00000000000 11717260147 017121 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/src/manifest 0000644 0002154 0303237 00000000130 11717260147 020644 0 ustar csnover allusers Manifest-Version: 1.0 Main-Class: org.dojotoolkit.shrinksafe.Main Class-Path: js.jar dojo-release-1.7.2-shrinksafe/src/org/ 0000755 0002154 0303237 00000000000 11717260147 017710 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/ 0000755 0002154 0303237 00000000000 11717260147 022251 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/ 0000755 0002154 0303237 00000000000 11717260147 024406 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/DebugData.java 0000644 0002154 0303237 00000002204 11717260147 027067 0 ustar csnover allusers /* * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Richard Backhouse */ package org.dojotoolkit.shrinksafe; /* * The class provides a simple data structure to collect debug information * for a given function. */ public class DebugData { public int start = 0; public int end = 0; public int compressedStart = 0; public int compressedEnd = 0; public String[] paramAndVarNames = null; } dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/ReplacedTokens.java 0000644 0002154 0303237 00000013401 11717260147 030153 0 ustar csnover allusers /* * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Richard Backhouse */ package org.dojotoolkit.shrinksafe; import java.util.Iterator; import java.util.Map; /* * This Class provides a container for the replaced tokens applied for a given scope * It provides a method to traverse down through the hierarchy to seach for a * replacement match. It also provides a method that generates debug information. */ public class ReplacedTokens { private int[] parents = null; private Map replacements = null; private Map lookup = null; private DebugData debugData = null; public ReplacedTokens(Map replacements, int[] parents, Map lookup, DebugData debugData) { this.replacements = replacements; this.parents = parents; this.lookup = lookup; this.debugData = debugData; } public String find(String token) { String replacedToken = null; if (replacements != null) { replacedToken = (String)replacements.get(token); } if (replacedToken == null) { for (int i = parents.length; i > 0; i--) { int parentPos = parents[i-1]; ReplacedTokens parent = (ReplacedTokens)lookup.get(new Integer(parentPos)); if (parent.replacements != null) { replacedToken = (String)parent.replacements.get(token); if (replacedToken != null) { break; } } } } if (replacedToken == null) { replacedToken = token; } return replacedToken; } public String printDebugData() { StringBuffer sb = new StringBuffer(); if (debugData != null) { sb.append("Start:"+debugData.start); sb.append(' '); sb.append("End:"+debugData.end); sb.append(' '); sb.append("Compressed Start:"+debugData.compressedStart); sb.append(' '); sb.append("Compressed End:"+debugData.compressedEnd); sb.append(' '); if (debugData.paramAndVarNames != null) { sb.append("Params and Vars: ["); for (String paramVar: debugData.paramAndVarNames) { sb.append(paramVar); sb.append(' '); } sb.append("]\n"); } if (replacements != null && replacements.size() > 0) { sb.append("\t"); sb.append("Replacements:\n"); for (Iterator itr = replacements.keySet().iterator(); itr.hasNext();) { String token = (String)itr.next(); String replacement = (String)replacements.get(token); if (!token.equals(replacement)) { sb.append("\t\t"); sb.append('['); sb.append(token); sb.append(']'); sb.append(" replaced with "); sb.append('['); sb.append(replacement); sb.append(']'); sb.append('\n'); } } sb.append("\n"); } for (int i = parents.length; i > 0; i--) { int parentPos = parents[i-1]; ReplacedTokens parent = (ReplacedTokens)lookup.get(new Integer(parentPos)); if (parent.replacements != null && parent.replacements.size() > 0) { sb.append("\t"); sb.append("Parent Replacements level ["+i+"]:\n"); for (Iterator itr = parent.replacements.keySet().iterator(); itr.hasNext();) { String token = (String)itr.next(); String replacement = (String)parent.replacements.get(token); if (!token.equals(replacement)) { sb.append("\t\t"); sb.append('['); sb.append(token); sb.append(']'); sb.append(" replaced with "); sb.append('['); sb.append(replacement); sb.append(']'); sb.append('\n'); } } sb.append("\n"); } } } return sb.toString(); } public String toJson() { StringBuffer json = new StringBuffer(); json.append('{'); if (debugData != null) { json.append("start: "+debugData.start); json.append(", "); json.append("end: "+debugData.end); json.append(", "); json.append("compressedStart: "+debugData.compressedStart); json.append(", "); json.append("compressedEnd: "+debugData.compressedEnd); json.append(", "); json.append("replacements: {"); if (replacements != null && replacements.size() > 0) { json.append(replacementsToJson(replacements)); } json.append('}'); if (parents.length > 0) { json.append(", "); json.append("parentReplacements: ["); } int count = 1; for (int i = 0; i < parents.length; i++) { json.append('{'); int parentPos = parents[i]; ReplacedTokens parent = (ReplacedTokens)lookup.get(new Integer(parentPos)); if (parent.replacements != null && parent.replacements.size() > 0) { json.append(replacementsToJson(parent.replacements)); } json.append('}'); if (count++ < parents.length) { json.append(", "); } } if (parents.length > 0) { json.append("]"); } } json.append("}"); return json.toString(); } private static String replacementsToJson(Map replacements) { StringBuffer sb = new StringBuffer(); int count = 1; for (Iterator itr = replacements.keySet().iterator(); itr.hasNext();) { String token = (String)itr.next(); String replacement = (String)replacements.get(token); sb.append("\""+replacement+'\"'); sb.append(" : "); sb.append("\""+token+"\""); if (count++ < replacements.size()) { sb.append(", "); } } return sb.toString(); } } dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/Main.java 0000644 0002154 0303237 00000021141 11717260147 026134 0 ustar csnover allusers /* * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alex Russell * Richard Backhouse */ package org.dojotoolkit.shrinksafe; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextAction; import org.mozilla.javascript.Kit; import org.mozilla.javascript.tools.ToolErrorReporter; import org.mozilla.javascript.tools.shell.Global; import org.mozilla.javascript.tools.shell.QuitAction; import org.mozilla.javascript.tools.shell.ShellContextFactory; public class Main { protected static final Global global = new Global(); protected static final ShellContextFactory shellContextFactory = new ShellContextFactory(); protected static ToolErrorReporter errorReporter; protected static int exitCode = 0; protected static boolean escapeUnicode = false; protected static String stripConsole = null; static { global.initQuitAction(new IProxy(IProxy.SYSTEM_EXIT, null)); } /** * Proxy class to avoid proliferation of anonymous classes. */ private static class IProxy implements ContextAction, QuitAction { private static final int PROCESS_FILES = 1; private static final int SYSTEM_EXIT = 3; private int type; private String[] args; IProxy(int type, String[] args) { this.type = type; this.args = args; } public Object run(Context cx) { if (type == PROCESS_FILES) { try { processFiles(cx, args); } catch (IOException ioe) { Context.reportError(ioe.toString()); } } else { throw Kit.codeBug(); } return null; } public void quit(Context cx, int exitCode) { if (type == SYSTEM_EXIT) { System.exit(exitCode); return; } throw Kit.codeBug(); } } public static void main(String[] args) { errorReporter = new ToolErrorReporter(false, global.getErr()); shellContextFactory.setErrorReporter(errorReporter); IProxy iproxy = new IProxy(IProxy.PROCESS_FILES, processOptions(args)); global.init(shellContextFactory); shellContextFactory.call(iproxy); } public static String[] processOptions(String args[]) { List fileList = new ArrayList(); String usageError = null; boolean showUsage = false; for (int i = 0; i < args.length; i++) { String arg = args[i]; if (!arg.startsWith("-")) { fileList.add(arg); } else if (arg.equals("-js-version")) { if (++i == args.length) { usageError = arg; } int version = 0; try { version = Integer.parseInt(args[i]); } catch (NumberFormatException ex) { usageError = args[i]; } if (!Context.isValidLanguageVersion(version)) { usageError = args[i]; } if (usageError != null) shellContextFactory.setLanguageVersion(version); } /* else if (arg.equals("-opt") || arg.equals("-O")) { if (++i == args.length) { usageError = arg; } int opt = 0; try { opt = Integer.parseInt(args[i]); } catch (NumberFormatException ex) { usageError = args[i]; } if (opt == -2) { // Compatibility with Cocoon Rhino fork opt = -1; } else if (!Context.isValidOptimizationLevel(opt)) { usageError = args[i]; } if (usageError != null) { shellContextFactory.setOptimizationLevel(opt); } } else if (arg.equals("-debug")) { shellContextFactory.setGeneratingDebug(true); } */ else if (arg.equals("-?") || arg.equals("-help")) { showUsage = true; } else if (arg.equals("-escape-unicode")) { escapeUnicode = true; } else if (arg.equals("-stripConsole")) { if (i >= (args.length-1)) { usageError = getMessage("msg.shell.stripConsoleMissingArg"); } else { stripConsole = args[++i]; if (!stripConsole.equals("normal") && !stripConsole.equals("warn") && !stripConsole.equals("all")) { usageError = getMessage("msg.shell.stripConsoleInvalid"); } } } } // print error and usage message if (usageError != null) { global.getOut().println(getMessage("msg.shell.invalid", usageError)); } if (usageError != null || showUsage) { global.getOut().println(getMessage("msg.shell.usage")); System.exit(1); } String[] files = new String[fileList.size()]; files = (String[])fileList.toArray(files); return files; } static void processFiles(Context cx, String[] files) throws IOException { StringBuffer cout = new StringBuffer(); if (files.length > 0) { for (int i=0; i < files.length; i++) { try { String source = (String)readFileOrUrl(files[i], true); cout.append(Compressor.compressScript(source, 0, 1, escapeUnicode, stripConsole)); } catch(IOException ex) { // continue processing files } } } else { byte[] data = Kit.readStream(global.getIn(), 4096); // Convert to String using the default encoding String source = new String(data); if (source != null) { cout.append(Compressor.compressScript(source, 0, 1, escapeUnicode, stripConsole)); } } global.getOut().println(cout); } private static Object readFileOrUrl(String path, boolean convertToString) throws IOException { URL url = null; // Assume path is URL if it contains a colon and there are at least // 2 characters in the protocol part. The later allows under Windows // to interpret paths with driver letter as file, not URL. if (path.indexOf(':') >= 2) { try { url = new URL(path); } catch (MalformedURLException ex) { } } InputStream is = null; int capacityHint = 0; if (url == null) { File file = new File(path); capacityHint = (int)file.length(); try { is = new FileInputStream(file); } catch (IOException ex) { Context.reportError(getMessage("msg.couldnt.open", path)); throw ex; } } else { try { URLConnection uc = url.openConnection(); is = uc.getInputStream(); capacityHint = uc.getContentLength(); // Ignore insane values for Content-Length if (capacityHint > (1 << 20)) { capacityHint = -1; } } catch (IOException ex) { Context.reportError(getMessage("msg.couldnt.open.url", url.toString(), ex.toString())); throw ex; } } if (capacityHint <= 0) { capacityHint = 4096; } byte[] data; try { try { is = new BufferedInputStream(is); data = Kit.readStream(is, capacityHint); } finally { is.close(); } } catch (IOException ex) { Context.reportError(ex.toString()); throw ex; } Object result; if (convertToString) { // Convert to String using the default encoding // TODO: Use 'charset=' argument of Content-Type if URL? result = new String(data); } else { result = data; } return result; } private static String getMessage(String messageId) { return getMessage(messageId, (Object []) null); } private static String getMessage(String messageId, String argument) { return getMessage(messageId, new Object[]{argument}); } private static String getMessage(String messageId, Object arg1, Object arg2) { return getMessage(messageId, new Object[]{arg1, arg2}); } private static String getMessage(String messageId, Object[] args) { Context cx = Context.getCurrentContext(); Locale locale = cx == null ? Locale.getDefault() : cx.getLocale(); ResourceBundle rb = ResourceBundle.getBundle("org.dojotoolkit.shrinksafe.resources.Messages", locale); String formatString = null; try { formatString = rb.getString(messageId); } catch (java.util.MissingResourceException mre) { throw new RuntimeException("no message resource found for message property " + messageId); } if (args == null) { return formatString; } else { MessageFormat formatter = new MessageFormat(formatString); return formatter.format(args); } } } dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/TokenMapper.java 0000644 0002154 0303237 00000022271 11717260147 027502 0 ustar csnover allusers /* * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alex Russell * Richard Backhouse */ package org.dojotoolkit.shrinksafe; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.mozilla.javascript.ScriptOrFnNode; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Token; public class TokenMapper { private List functionBracePositions = new ArrayList(); /** * Map of all replaced tokens */ private List replacedTokens = new ArrayList(); /** * Map of each Function node and all the variables in its current function * scope, other variables found while traversing the prototype chain and * variables found in the top-level scope. */ private List functionVarMappings = new ArrayList(); private Map debugDataList = new HashMap(); private int functionNum = 0; private int parentScope = 0; private int lastTokenCount = 0; public TokenMapper(ScriptOrFnNode parseTree) { collectFunctionMappings(parseTree); } public void incrementFunctionNumber() { functionNum++; } /** * Generate new compressed tokens *
* * @param token * value of the string token * @param hasNewMapping * boolean value indicating a new variable binding * @return compressed token */ private String getMappedToken(String token, boolean hasNewMapping) { String newToken = null; Map tokens = null; String blank = new String(""); int localScope = functionBracePositions.size() - 1; String oldToken = getPreviousTokenMapping(token, hasNewMapping); if (!oldToken.equalsIgnoreCase(blank)) { return oldToken; } else if ((hasNewMapping || isInScopeChain(token))) { newToken = new String("_" + Integer.toHexString(++lastTokenCount)); if (newToken.length() >= token.length() && token.charAt(0) != '_') { newToken = token; lastTokenCount--; } tokens = (Map) replacedTokens.get(hasNewMapping ? localScope : parentScope); tokens.put(token, newToken); return newToken; } return token; } /** * Checks for variable names in prototype chain *
* * @param token * value of the string token * @return boolean value indicating if the token is present in the chained * scope */ private boolean isInScopeChain(String token) { int scope = functionBracePositions.size(); Map chainedScopeVars = (Map) functionVarMappings.get(functionNum); if (!chainedScopeVars.isEmpty()) { for (int i = scope; i > 0; i--) { if (chainedScopeVars.containsKey(new Integer(i))) { parentScope = i - 1; List temp = Arrays.asList((String[]) chainedScopeVars.get(new Integer(i))); if (temp.indexOf(token) != -1) { return true; } } } } return false; } /** * Checks previous token mapping *
* * @param token * value of the string token * @param hasNewMapping * boolean value indicating a new variable binding * @return string value of the previous token or blank string */ private String getPreviousTokenMapping(String token, boolean hasNewMapping) { String result = new String(""); int scope = replacedTokens.size() - 1; if (scope < 0) { return result; } if (hasNewMapping) { Map tokens = (Map) (replacedTokens.get(scope)); if (tokens.containsKey(token)) { result = (String) tokens.get(token); return result; } } else { for (int i = scope; i > -1; i--) { Map tokens = (Map) (replacedTokens.get(i)); if (tokens.containsKey(token)) { result = (String) tokens.get(token); return result; } } } return result; } /** * Generate mappings for each Function node and parameters and variables * names associated with it. *
* * @param parseTree * Mapping for each function node and corresponding parameters & * variables names */ private void collectFunctionMappings(ScriptOrFnNode parseTree) { int level = -1; collectFuncNodes(parseTree, level, null); } /** * Recursive method to traverse all Function nodes *
* * @param parseTree * Mapping for each function node and corresponding parameters & * variables names * @param level * scoping level */ private void collectFuncNodes(ScriptOrFnNode parseTree, int level, ScriptOrFnNode parent) { level++; DebugData debugData = new DebugData(); debugData.start = parseTree.getBaseLineno(); debugData.end = parseTree.getEndLineno(); debugData.paramAndVarNames = parseTree.getParamAndVarNames(); debugDataList.put(new Integer(parseTree.getEncodedSourceStart()), debugData); functionVarMappings.add(new HashMap()); Map bindingNames = (Map) functionVarMappings.get(functionVarMappings.size() - 1); bindingNames.put(new Integer(level), parseTree.getParamAndVarNames()); if (parent != null) { bindingNames.put(new Integer(level-1), parent.getParamAndVarNames()); } int nestedCount = parseTree.getFunctionCount(); for (int i = 0; i != nestedCount; ++i) { collectFuncNodes(parseTree.getFunctionNode(i), level, parseTree); bindingNames = (Map) functionVarMappings.get(functionVarMappings.size() - 1); bindingNames.put(new Integer(level), parseTree.getParamAndVarNames()); } } /** * Compress the script *
* * @param encodedSource * encoded source string * @param offset * position within the encoded source * @param asQuotedString * boolean value indicating a quoted string * @param sb * String buffer reference * @param prevToken * Previous token in encoded source * @param inArgsList * boolean value indicating position inside arguments list * @param currentLevel * embeded function level * @param parseTree * Mapping of each function node and corresponding parameters & * variables names * @return compressed script */ public int sourceCompress(String encodedSource, int offset, boolean asQuotedString, StringBuffer sb, int prevToken, boolean inArgsList, int currentLevel, ReplacedTokens replacedTokens) { boolean hasNewMapping = false; int length = encodedSource.charAt(offset); ++offset; if ((0x8000 & length) != 0) { length = ((0x7FFF & length) << 16) | encodedSource.charAt(offset); ++offset; } String str = encodedSource.substring(offset, offset + length); if ((prevToken == Token.VAR) || (inArgsList)) { hasNewMapping = true; } if (sb != null) { String sourceStr = new String(str); if (((functionBracePositions.size() > 0) && (currentLevel >= (((Integer) functionBracePositions.get(functionBracePositions.size() - 1)).intValue()))) || (inArgsList)) { if (prevToken != Token.DOT) { // Look for replacement token in provided lookup object. str = replacedTokens.find(str); } } if ((!inArgsList) && (asQuotedString)) { if ((prevToken == Token.LC) || (prevToken == Token.COMMA)) { str = sourceStr; } } if (!asQuotedString) { sb.append(str); } else { sb.append('"'); sb.append(ScriptRuntime.escapeString(str)); sb.append('"'); } } else if (((functionBracePositions.size() > 0) && (currentLevel >= (((Integer) functionBracePositions.get(functionBracePositions.size() - 1)).intValue()))) || (inArgsList)) { if (prevToken != Token.DOT) { getMappedToken(str, hasNewMapping); } } return offset + length; } public void enterNestingLevel(int braceNesting) { functionBracePositions.add(new Integer(braceNesting + 1)); replacedTokens.add(new HashMap()); } public boolean leaveNestingLevel(int braceNesting) { boolean tokensRemoved = false; Integer bn = new Integer(braceNesting); if ((functionBracePositions.contains(bn)) && (replacedTokens.size() > 0)) { // remove our mappings now! int scopedSize = replacedTokens.size(); replacedTokens.remove(scopedSize - 1); functionBracePositions.remove(bn); tokensRemoved = true; } return tokensRemoved; } public Map getCurrentTokens() { Map m = null; if (replacedTokens.size() > 0) { m = (Map)replacedTokens.get(replacedTokens.size() - 1); } return m; } public DebugData getDebugData(Integer functionPosition) { return (DebugData)debugDataList.get(functionPosition); } public void reset() { functionNum = 0; parentScope = 0; lastTokenCount = 0; functionBracePositions = new ArrayList(); replacedTokens = new ArrayList(); } } dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/resources/ 0000755 0002154 0303237 00000000000 11717260147 026420 5 ustar csnover allusers dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/resources/Messages.properties 0000644 0002154 0303237 00000003673 11717260147 032316 0 ustar csnover allusers # Version: MPL 1.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is Rhino code, released # May 6, 1999. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1997-1999 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Alex Russell # Richard Backhouse msg.couldnt.open =\ Couldn''t open file "{0}". msg.couldnt.open.url =\ Couldn''t open URL "{0}: {1}". msg.shell.invalid =\ Invalid option "{0}" msg.shell.stripConsoleMissingArg =\ No behaviour provided for stripConsole msg.shell.stripConsoleInvalid =\ Invalid value provided for stripConsole msg.shell.usage =\ Dojo ShrinkSafe 2.0 $Rev: 22183 $ \n\ \n\ Usage: java -jar shrinksafe.jar [options...] [files or urls]\n\ Valid options are:\n\ \ -?, -help Displays help messages.\n\ \ -escape-unicode Use Javascript \\u#### notation for non-ASCII Characters.\n\ \ -js-version n Sets the version of Javascript used. See the -version\n\ \ option in Rhino for info. e.g. 100|110|120|130|140\n\ \ -stripConsole [ normal | warn | all ]\n\ \ If not specified, all console calls are left alone.\n\ \ normal - all console calls except warn and error are stripped.\n\ \ warn - all console calls except error are stripped.\n\ \ all - all console calls are stripped.\n\ dojo-release-1.7.2-shrinksafe/src/org/dojotoolkit/shrinksafe/Compressor.java 0000644 0002154 0303237 00000113151 11717260147 027407 0 ustar csnover allusers /* * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alex Russell * Richard Backhouse */ package org.dojotoolkit.shrinksafe; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.mozilla.javascript.CompilerEnvirons; import org.mozilla.javascript.Decompiler; import org.mozilla.javascript.FunctionNode; import org.mozilla.javascript.Interpreter; import org.mozilla.javascript.Kit; import org.mozilla.javascript.Parser; import org.mozilla.javascript.ScriptOrFnNode; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Token; import org.mozilla.javascript.UintMap; /** * @author rbackhouse * */ public class Compressor { private static final int FUNCTION_END = Token.LAST_TOKEN + 1; /** * Compress the script *
* * @param encodedSource encoded source string * @param flags Flags specifying format of decompilation output * @param properties Decompilation properties * @param parseTree Mapping for each function node and corresponding parameters & variables names * @return compressed script */ private static String compress(String encodedSource, int flags, UintMap properties, ScriptOrFnNode parseTree, boolean escapeUnicode, String stripConsole, TokenMapper tm, Map replacedTokensLookup){ int indent = properties.getInt(Decompiler.INITIAL_INDENT_PROP, 0); if (indent < 0) throw new IllegalArgumentException(); int indentGap = properties.getInt(Decompiler.INDENT_GAP_PROP, 4); if (indentGap < 0) throw new IllegalArgumentException(); int caseGap = properties.getInt(Decompiler.CASE_GAP_PROP, 2); if (caseGap < 0) throw new IllegalArgumentException(); String stripConsoleRegex = "assert|count|debug|dir|dirxml|group|groupEnd|info|profile|profileEnd|time|timeEnd|trace|log"; if (stripConsole == null) { // may be null if unspecified on Main cmd line stripConsoleRegex = null; } else if (stripConsole.equals("normal")) { // leave default } else if (stripConsole.equals("warn")) { stripConsoleRegex += "|warn"; } else if (stripConsole.equals("all")) { stripConsoleRegex += "|warn|error"; } else { throw new IllegalArgumentException("unrecognised value for stripConsole: " + stripConsole + "!"); } Pattern stripConsolePattern = null; if (stripConsoleRegex != null) { stripConsolePattern = Pattern.compile(stripConsoleRegex); } StringBuffer result = new StringBuffer(); boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG)); int braceNesting = 0; boolean afterFirstEOL = false; int i = 0; int prevToken = 0; boolean primeFunctionNesting = false; boolean inArgsList = false; boolean primeInArgsList = false; boolean discardingConsole = false; // control skipping "console.stuff()" int consoleParenCount = 0; // counter for parenthesis counting StringBuffer discardMe = new StringBuffer(); // throwaway buffer ReplacedTokens dummyTokens = new ReplacedTokens(new HashMap(), new int[]{}, replacedTokensLookup, null); int lastMeaningfulToken = Token.SEMI; int lastMeaningfulTokenBeforeConsole = Token.SEMI; int topFunctionType; if (encodedSource.charAt(i) == Token.SCRIPT) { ++i; topFunctionType = -1; } else { topFunctionType = encodedSource.charAt(i + 1); } if (!toSource) { // add an initial newline to exactly match js. // result.append('\n'); for (int j = 0; j < indent; j++){ // result.append(' '); result.append(""); } } else { if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) { result.append('('); } } Stack positionStack = new Stack(); Stack functionPositionStack = new Stack(); int length = encodedSource.length(); int lineCount = 1; while (i < length) { if(i>0){ prevToken = encodedSource.charAt(i-1); } if (discardingConsole) { // while we are skipping a console command, discard tokens int thisToken = encodedSource.charAt(i); /* Logic for controlling state of discardingConsole */ switch (thisToken) { case Token.LP: consoleParenCount++; break; case Token.RP: consoleParenCount--; if (consoleParenCount == 0) { // paren count fell to zero, must be end of console call discardingConsole = false; if (i < (length - 1)) { int nextToken = getNext(encodedSource, length, i); if ((lastMeaningfulTokenBeforeConsole != Token.SEMI && lastMeaningfulTokenBeforeConsole != Token.LC && lastMeaningfulTokenBeforeConsole != Token.RC) || nextToken != Token.SEMI) { // Either the previous or the following token // may use our return value, insert undefined // e.g. true ? console.log("bizarre") : (bar = true); result.append("undefined"); } else { if (Token.SEMI == nextToken) { // munch following semicolon i++; } } } if ((i < (length - 1)) && (Token.EOL == getNext(encodedSource, length, i))) { // as a nicety, munch following linefeed i++; } } break; } /* * advance i - borrow code from later switch statements (could * mingle this whole discardingConsole block in with rest of * function but it would be _ugly_) Use discardMe in place of * result, so we don't use the processed source Specific case * blocks for all source elements > 1 char long */ switch (thisToken) { case Token.NAME: case Token.REGEXP: int jumpPos = getSourceStringEnd(encodedSource, i + 1, escapeUnicode); if (Token.OBJECTLIT == encodedSource.charAt(jumpPos)) { i = printSourceString(encodedSource, i + 1, false, discardMe, escapeUnicode); } else { i = tm.sourceCompress(encodedSource, i + 1, false, discardMe, prevToken, inArgsList, braceNesting, dummyTokens); } break; case Token.STRING: i = printSourceString(encodedSource, i + 1, true, discardMe, escapeUnicode); break; case Token.NUMBER: i = printSourceNumber(encodedSource, i + 1, discardMe); break; default: // all plain tokens (no data to skip) i++; } // while discarding console, avoid the normal processing continue; } // System.out.println(Token.name(getNext(source, length, i))); int thisToken = encodedSource.charAt(i); switch(thisToken) { case Token.NAME: case Token.REGEXP: // re-wrapped in '/'s in parser... int jumpPos = getSourceStringEnd(encodedSource, i+1, escapeUnicode); if (stripConsolePattern != null && thisToken == Token.NAME) { // Check to see if this is a console.something() call that we // care about, if so switch on discardingConsole int nextTokenAt = tm.sourceCompress(encodedSource, i + 1, false, discardMe, prevToken, inArgsList, braceNesting, dummyTokens); if (encodedSource.substring(i+2, i+2+encodedSource.charAt(i+1)).equals("console") && (encodedSource.charAt(nextTokenAt) == Token.DOT)) { // Find the name of the console method and check it int afterFnName = printSourceString(encodedSource, nextTokenAt+2, false, discardMe, escapeUnicode); Matcher m = stripConsolePattern.matcher(encodedSource.substring(nextTokenAt + 3, afterFnName)); if (m.matches()) { // Must be an open parenthesis e.g. "console.log(" if (encodedSource.charAt(afterFnName) == Token.LP) { discardingConsole = true; consoleParenCount = 0; lastMeaningfulTokenBeforeConsole = lastMeaningfulToken; continue; } } } } if(Token.OBJECTLIT == encodedSource.charAt(jumpPos)){ i = printSourceString(encodedSource, i + 1, false, result, escapeUnicode); }else{ ReplacedTokens replacedTokens = null; if (positionStack.size() > 0) { Integer pos = (Integer)positionStack.peek(); replacedTokens = (ReplacedTokens)replacedTokensLookup.get(pos); } else { replacedTokens = new ReplacedTokens(new HashMap(), new int[]{}, replacedTokensLookup, null); } i = tm.sourceCompress( encodedSource, i + 1, false, result, prevToken, inArgsList, braceNesting, replacedTokens); } continue; case Token.STRING: // NOTE: this is the disabled "string munging" code provided in bugs.dojotoolkit.org/ticket/8828 // simply uncomment this block, and run the build.sh script located in the root shrinksafe folder. // there is a far-egde-case this is deemed unsafe in, so is entirely disabled for sanity of devs. // // StringBuffer buf = new StringBuffer(); // i--; // do { // i++; // i = printSourceString(encodedSource, i + 1, false, buf, escapeUnicode); // } while(Token.ADD == encodedSource.charAt(i) && // Token.STRING == getNext(encodedSource, length, i)); // result.append('"'); // result.append(escapeString(buf.toString(), escapeUnicode)); // result.append('"'); // // now comment out this line to complete the patch: i = printSourceString(encodedSource, i + 1, true, result, escapeUnicode); continue; case Token.NUMBER: i = printSourceNumber(encodedSource, i + 1, result); continue; case Token.TRUE: result.append("true"); break; case Token.FALSE: result.append("false"); break; case Token.NULL: result.append("null"); break; case Token.THIS: result.append("this"); break; case Token.FUNCTION: { ++i; // skip function type tm.incrementFunctionNumber(); primeInArgsList = true; primeFunctionNesting = true; result.append("function"); if (Token.LP != getNext(encodedSource, length, i)) { result.append(' '); } Integer functionPos = new Integer(i-1); functionPositionStack.push(functionPos); DebugData debugData = tm.getDebugData(functionPos); debugData.compressedStart = lineCount; break; } case FUNCTION_END: { Integer functionPos = (Integer)functionPositionStack.pop(); DebugData debugData = tm.getDebugData(functionPos); debugData.compressedEnd = lineCount; break; } case Token.COMMA: result.append(","); break; case Token.LC: ++braceNesting; if (Token.EOL == getNext(encodedSource, length, i)){ indent += indentGap; } result.append('{'); // // result.append('\n'); break; case Token.RC: { if (tm.leaveNestingLevel(braceNesting)) { positionStack.pop(); } --braceNesting; /* don't print the closing RC if it closes the * toplevel function and we're called from * decompileFunctionBody. */ if(justFunctionBody && braceNesting == 0){ break; } // // result.append('\n'); result.append('}'); // // result.append(' '); switch (getNext(encodedSource, length, i)) { case Token.EOL: case FUNCTION_END: if ( (getNext(encodedSource, length, i+1) != Token.SEMI) && (getNext(encodedSource, length, i+1) != Token.LP) && (getNext(encodedSource, length, i+1) != Token.RP) && (getNext(encodedSource, length, i+1) != Token.RB) && (getNext(encodedSource, length, i+1) != Token.RC) && (getNext(encodedSource, length, i+1) != Token.COMMA) && (getNext(encodedSource, length, i+1) != Token.COLON) && (getNext(encodedSource, length, i+1) != Token.DOT) && (getNext(encodedSource, length, i) == FUNCTION_END ) ){ result.append(';'); } indent -= indentGap; break; case Token.WHILE: case Token.ELSE: indent -= indentGap; // result.append(' '); result.append(""); break; } break; } case Token.LP: if(primeInArgsList){ inArgsList = true; primeInArgsList = false; } if(primeFunctionNesting){ positionStack.push(new Integer(i)); tm.enterNestingLevel(braceNesting); primeFunctionNesting = false; } result.append('('); break; case Token.RP: if(inArgsList){ inArgsList = false; } result.append(')'); /* if (Token.LC == getNext(source, length, i)){ result.append(' '); } */ break; case Token.LB: result.append('['); break; case Token.RB: result.append(']'); break; case Token.EOL: { if (toSource) break; boolean newLine = true; if (!afterFirstEOL) { afterFirstEOL = true; if (justFunctionBody) { /* throw away just added 'function name(...) {' * and restore the original indent */ result.setLength(0); indent -= indentGap; newLine = false; } } if (newLine) { result.append('\n'); lineCount++; } /* add indent if any tokens remain, * less setback if next token is * a label, case or default. */ if (i + 1 < length) { int less = 0; int nextToken = encodedSource.charAt(i + 1); if (nextToken == Token.CASE || nextToken == Token.DEFAULT) { less = indentGap - caseGap; } else if (nextToken == Token.RC) { less = indentGap; } /* elaborate check against label... skip past a * following inlined NAME and look for a COLON. */ else if (nextToken == Token.NAME) { int afterName = getSourceStringEnd(encodedSource, i + 2, escapeUnicode); if (encodedSource.charAt(afterName) == Token.COLON) less = indentGap; } for (; less < indent; less++){ // result.append(' '); result.append(""); } } break; } case Token.DOT: result.append('.'); break; case Token.NEW: result.append("new "); break; case Token.DELPROP: result.append("delete "); break; case Token.IF: result.append("if"); break; case Token.ELSE: result.append("else"); break; case Token.FOR: result.append("for"); break; case Token.IN: result.append(" in "); break; case Token.WITH: result.append("with"); break; case Token.WHILE: result.append("while"); break; case Token.DO: result.append("do"); break; case Token.TRY: result.append("try"); break; case Token.CATCH: result.append("catch"); break; case Token.FINALLY: result.append("finally"); break; case Token.THROW: result.append("throw "); break; case Token.SWITCH: result.append("switch"); break; case Token.BREAK: result.append("break"); if(Token.NAME == getNext(encodedSource, length, i)){ result.append(' '); } break; case Token.CONTINUE: result.append("continue"); if(Token.NAME == getNext(encodedSource, length, i)){ result.append(' '); } break; case Token.CASE: result.append("case "); break; case Token.DEFAULT: result.append("default"); break; case Token.RETURN: result.append("return"); if(Token.SEMI != getNext(encodedSource, length, i)){ result.append(' '); } break; case Token.VAR: result.append("var "); break; case Token.SEMI: result.append(';'); // result.append('\n'); /* if (Token.EOL != getNext(source, length, i)) { // separators in FOR result.append(' '); } */ break; case Token.ASSIGN: result.append("="); break; case Token.ASSIGN_ADD: result.append("+="); break; case Token.ASSIGN_SUB: result.append("-="); break; case Token.ASSIGN_MUL: result.append("*="); break; case Token.ASSIGN_DIV: result.append("/="); break; case Token.ASSIGN_MOD: result.append("%="); break; case Token.ASSIGN_BITOR: result.append("|="); break; case Token.ASSIGN_BITXOR: result.append("^="); break; case Token.ASSIGN_BITAND: result.append("&="); break; case Token.ASSIGN_LSH: result.append("<<="); break; case Token.ASSIGN_RSH: result.append(">>="); break; case Token.ASSIGN_URSH: result.append(">>>="); break; case Token.HOOK: result.append("?"); break; case Token.OBJECTLIT: // pun OBJECTLIT to mean colon in objlit property // initialization. // This needs to be distinct from COLON in the general case // to distinguish from the colon in a ternary... which needs // different spacing. result.append(':'); break; case Token.COLON: if (Token.EOL == getNext(encodedSource, length, i)) // it's the end of a label result.append(':'); else // it's the middle part of a ternary result.append(":"); break; case Token.OR: result.append("||"); break; case Token.AND: result.append("&&"); break; case Token.BITOR: result.append("|"); break; case Token.BITXOR: result.append("^"); break; case Token.BITAND: result.append("&"); break; case Token.SHEQ: result.append("==="); break; case Token.SHNE: result.append("!=="); break; case Token.EQ: result.append("=="); break; case Token.NE: result.append("!="); break; case Token.LE: result.append("<="); break; case Token.LT: result.append("<"); break; case Token.GE: result.append(">="); break; case Token.GT: result.append(">"); break; case Token.INSTANCEOF: // FIXME: does this really need leading space? result.append(" instanceof "); break; case Token.LSH: result.append("<<"); break; case Token.RSH: result.append(">>"); break; case Token.URSH: result.append(">>>"); break; case Token.TYPEOF: result.append("typeof "); break; case Token.VOID: result.append("void "); break; case Token.NOT: result.append('!'); break; case Token.BITNOT: result.append('~'); break; case Token.POS: result.append('+'); break; case Token.NEG: result.append('-'); break; case Token.INC: if(Token.ADD == prevToken){ result.append(' '); } result.append("++"); if(Token.ADD == getNext(encodedSource, length, i)){ result.append(' '); } break; case Token.DEC: if(Token.SUB == prevToken){ result.append(' '); } result.append("--"); if(Token.SUB == getNext(encodedSource, length, i)){ result.append(' '); } break; case Token.ADD: result.append("+"); int nextToken = encodedSource.charAt(i + 1); if (nextToken == Token.POS) { result.append(' '); } break; case Token.SUB: result.append("-"); nextToken = encodedSource.charAt(i + 1); if (nextToken == Token.NEG) { result.append(' '); } break; case Token.MUL: result.append("*"); break; case Token.DIV: result.append("/"); break; case Token.MOD: result.append("%"); break; case Token.COLONCOLON: result.append("::"); break; case Token.DOTDOT: result.append(".."); break; case Token.XMLATTR: result.append('@'); break; case Token.DEBUGGER: System.out.println("WARNING: Found a `debugger;` statement in code being compressed"); result.append("debugger"); break; default: // If we don't know how to decompile it, raise an exception. throw new RuntimeException(); } if (thisToken != Token.EOL) { lastMeaningfulToken = thisToken; } ++i; } if (!toSource) { // add that trailing newline if it's an outermost function. // if (!justFunctionBody){ // result.append('\n'); // } } else { if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) { result.append(')'); } } return result.toString(); } /** * Collect the replaced tokens and store them in a lookup table for the next * source pass. * * @param encodedSource encoded source string * @param escapeUnicode escape chars with unicode. * @param tm token mapper object. * @return Map containing replaced tokens lookup information */ private static Map collectReplacedTokens(String encodedSource, boolean escapeUnicode, TokenMapper tm) { int length = encodedSource.length(); int i = 0; int prevToken = 0; int braceNesting = 0; boolean inArgsList = false; boolean primeFunctionNesting = false; boolean primeInArgsList = false; if (encodedSource.charAt(i) == Token.SCRIPT) { ++i; } Stack positionStack = new Stack(); Stack functionPositionStack = new Stack(); Map tokenLookup = new HashMap(); while (i < length) { if (i > 0) { prevToken = encodedSource.charAt(i - 1); } switch (encodedSource.charAt(i)) { case Token.NAME: case Token.REGEXP: { int jumpPos = getSourceStringEnd(encodedSource, i + 1, escapeUnicode); if (Token.OBJECTLIT == encodedSource.charAt(jumpPos)) { i = printSourceString(encodedSource, i + 1, false, null, escapeUnicode); } else { i = tm.sourceCompress(encodedSource, i + 1, false, null, prevToken, inArgsList, braceNesting, null); } continue; } case Token.STRING: { i = printSourceString(encodedSource, i + 1, true, null, escapeUnicode); continue; } case Token.NUMBER: { i = printSourceNumber(encodedSource, i + 1, null); continue; } case Token.FUNCTION: { ++i; // skip function type tm.incrementFunctionNumber(); primeInArgsList = true; primeFunctionNesting = true; functionPositionStack.push(new Integer(i-1)); break; } case Token.LC: { ++braceNesting; break; } case Token.RC: { Map m = tm.getCurrentTokens(); if (tm.leaveNestingLevel(braceNesting)) { Integer pos = (Integer)positionStack.pop(); Integer functionPos = (Integer)functionPositionStack.pop(); int[] parents = new int[positionStack.size()]; int idx = 0; for (Iterator itr = positionStack.iterator(); itr.hasNext();) { parents[idx++] = ((Integer)itr.next()).intValue(); } DebugData debugData = tm.getDebugData(functionPos); ReplacedTokens replacedTokens = new ReplacedTokens(m, parents, tokenLookup, debugData); tokenLookup.put(pos, replacedTokens); } --braceNesting; break; } case Token.LP: { if (primeInArgsList) { inArgsList = true; primeInArgsList = false; } if (primeFunctionNesting) { positionStack.push(new Integer(i)); tm.enterNestingLevel(braceNesting); primeFunctionNesting = false; } break; } case Token.RP: { if (inArgsList) { inArgsList = false; } break; } } ++i; } return tokenLookup; } private static int getNext(String source, int length, int i) { return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF; } private static int getSourceStringEnd(String source, int offset, boolean escapeUnicode) { return printSourceString(source, offset, false, null, escapeUnicode); } private static int printSourceString(String source, int offset, boolean asQuotedString, StringBuffer sb, boolean escapeUnicode) { int length = source.charAt(offset); ++offset; if ((0x8000 & length) != 0) { length = ((0x7FFF & length) << 16) | source.charAt(offset); ++offset; } if (sb != null) { String str = source.substring(offset, offset + length); if (!asQuotedString) { sb.append(str); } else { sb.append('"'); sb.append(escapeString(str, escapeUnicode)); sb.append('"'); } } return offset + length; } private static int printSourceNumber(String source, int offset, StringBuffer sb) { double number = 0.0; char type = source.charAt(offset); ++offset; if (type == 'S') { if (sb != null) { int ival = source.charAt(offset); number = ival; } ++offset; } else if (type == 'J' || type == 'D') { if (sb != null) { long lbits; lbits = (long) source.charAt(offset) << 48; lbits |= (long) source.charAt(offset + 1) << 32; lbits |= (long) source.charAt(offset + 2) << 16; lbits |= source.charAt(offset + 3); if (type == 'J') { number = lbits; } else { number = Double.longBitsToDouble(lbits); } } offset += 4; } else { // Bad source throw new RuntimeException(); } if (sb != null) { sb.append(ScriptRuntime.numberToString(number, 10)); } return offset; } private static String escapeString(String s, boolean escapeUnicode) { return escapeString(s, '"', escapeUnicode); } private static String escapeString(String s, char escapeQuote, boolean escapeUnicode) { if (!(escapeQuote == '"' || escapeQuote == '\'')) Kit.codeBug(); StringBuffer sb = null; for(int i = 0, L = s.length(); i != L; ++i) { int c = s.charAt(i); if (' ' <= c && c <= '~' && c != escapeQuote && c != '\\') { // an ordinary print character (like C isprint()) and not " // or \ . if (sb != null) { sb.append((char)c); } continue; } if (sb == null) { sb = new StringBuffer(L + 3); sb.append(s); sb.setLength(i); } int escape = -1; switch (c) { case '\b': escape = 'b'; break; case '\f': escape = 'f'; break; case '\n': escape = 'n'; break; case '\r': escape = 'r'; break; case '\t': escape = 't'; break; case 0xb: escape = 'v'; break; // Java lacks \v. case ' ': escape = ' '; break; case '\\': escape = '\\'; break; } if (escape >= 0) { // an \escaped sort of character sb.append('\\'); sb.append((char)escape); } else if (c == escapeQuote) { sb.append('\\'); sb.append(escapeQuote); } else { if (escapeUnicode || c == 0) { // always escape the null character (#5027) int hexSize; if (c < 256) { // 2-digit hex sb.append("\\x"); hexSize = 2; } else { // Unicode. sb.append("\\u"); hexSize = 4; } // append hexadecimal form of c left-padded with 0 for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) { int digit = 0xf & (c >> shift); int hc = (digit < 10) ? '0' + digit : 'a' - 10 + digit; sb.append((char)hc); } } else { sb.append((char)c); } } } return (sb == null) ? s : sb.toString(); } public static final String compressScript(String source, int indent, int lineno, String stripConsole) { return compressScript(source, indent, lineno, false, stripConsole); } public static final String compressScript(String source, int indent, int lineno, boolean escapeUnicode, String stripConsole) { return compressScript(source, indent, lineno, escapeUnicode, stripConsole, null); } public static final String compressScript(String source, int indent, int lineno, boolean escapeUnicode, String stripConsole, StringBuffer debugData) { CompilerEnvirons compilerEnv = new CompilerEnvirons(); Parser parser = new Parser(compilerEnv, compilerEnv.getErrorReporter()); ScriptOrFnNode tree = parser.parse(source, null, lineno); String encodedSource = parser.getEncodedSource(); if (encodedSource.length() == 0) { return ""; } Interpreter compiler = new Interpreter(); compiler.compile(compilerEnv, tree, encodedSource, false); UintMap properties = new UintMap(1); properties.put(Decompiler.INITIAL_INDENT_PROP, indent); TokenMapper tm = new TokenMapper(tree); Map replacedTokensLookup = collectReplacedTokens(encodedSource, escapeUnicode, tm); tm.reset(); String compressedSource = compress(encodedSource, 0, properties, tree, escapeUnicode, stripConsole, tm, replacedTokensLookup); if (debugData != null) { debugData.append("[\n"); int count = 1; for (Iterator itr = replacedTokensLookup.keySet().iterator(); itr.hasNext();) { Integer pos = (Integer)itr.next(); ReplacedTokens replacedTokens = (ReplacedTokens)replacedTokensLookup.get(pos); debugData.append(replacedTokens.toJson()); if (count++ < replacedTokensLookup.size()) { debugData.append(','); } debugData.append("\n"); } debugData.append("]"); } return compressedSource; } } dojo-release-1.7.2-shrinksafe/MPL-1.1.html 0000644 0002154 0303237 00000065506 11717260147 020161 0 ustar csnover allusers
means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is:
The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:
Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license
The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5.
Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.
You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code.
If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained.
If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the legal file.
Contributor represents that, except as disclosed pursuant to Section 3.4 (a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License.
You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
You may distribute Covered Code in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code.
If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the legal file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code.
Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.
Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License.
If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.)
Covered code is provided under this license on an "as is" basis, without warranty of any kind, either expressed or implied, including, without limitation, warranties that the covered code is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the covered code is with you. Should any covered code prove defective in any respect, you (not the initial developer or any other contributor) assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty constitutes an essential part of this license. No use of any covered code is authorized hereunder except under this disclaimer.
8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that:
8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination.
Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall you, the initial developer, any other contributor, or any distributor of covered code, or any supplier of any of such parties, be liable to any person for any indirect, special, incidental, or consequential damages of any character including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to you.
The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein.
This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License.
As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A.
"The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is ______________________________________. The Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License."
NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications. dojo-release-1.7.2-shrinksafe/build.sh 0000755 0002154 0303237 00000001073 11717260147 017771 0 ustar csnover allusers #!/bin/sh RHINO=../js.jar TEST=$1 # create shrinksafe.jar from src/ rm -rf bin mkdir bin cd src javac -classpath $RHINO:. -d ../bin org/dojotoolkit/shrinksafe/Main.java mkdir ../bin/org/dojotoolkit/shrinksafe/resources cp org/dojotoolkit/shrinksafe/resources/Messages.properties ../bin/org/dojotoolkit/shrinksafe/resources/Messages.properties cd ../bin jar cfm ../shrinksafe.jar ../src/manifest * cd .. rm -rf bin # call build.sh test to run the unit tests immediately if [ "$TEST" == "test" ]; then echo "Running tests." cd tests ./runner.sh #| grep errors -1 fi dojo-release-1.7.2-shrinksafe/README 0000644 0002154 0303237 00000001135 11717260147 017212 0 ustar csnover allusers shrinksafe.jar requires js.jar (Rhino) in the same directory. Usage: java -jar shrinksafe.jar somescript.js > minifiedscript.js There is a build-time version dependency between shrinksafe.jar and js.jar. Shrinksafe must be built and used with a particular version of Rhino. To build, run build.sh in this directory. Mozilla Rhino is licensed under MPL 1.1 (see LICENSE) and is available from http://www.mozilla.org/rhino. shrinksafe.jar is known to work with these Rhino versions: - 1.7R1 This version of ShrinkSafe will be incompatible with Rhino 1.7R3 and beyond due to changes in the Rhino API.