uglify-js
Advanced tools
+13
-13
@@ -47,3 +47,3 @@ /*********************************************************************** | ||
| var builtins = function() { | ||
| var names = []; | ||
| var names = new Dictionary(); | ||
| // NaN will be included due to Number.NaN | ||
@@ -76,6 +76,6 @@ [ | ||
| }); | ||
| return makePredicate(names); | ||
| return names; | ||
| function add(name) { | ||
| names.push(name); | ||
| names.set(name, true); | ||
| } | ||
@@ -121,5 +121,5 @@ }(); | ||
| var reserved = Object.create(options.builtins ? null : builtins); | ||
| var reserved = options.builtins ? new Dictionary() : builtins.clone(); | ||
| if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) { | ||
| reserved[name] = true; | ||
| reserved.set(name, true); | ||
| }); | ||
@@ -132,3 +132,3 @@ | ||
| cache.each(function(name) { | ||
| reserved[name] = true; | ||
| reserved.set(name, true); | ||
| }); | ||
@@ -148,4 +148,4 @@ } else { | ||
| var names_to_mangle = Object.create(null); | ||
| var unmangleable = Object.create(reserved); | ||
| var names_to_mangle = new Dictionary(); | ||
| var unmangleable = reserved.clone(); | ||
@@ -219,3 +219,3 @@ // step 1: find candidates to mangle | ||
| function can_mangle(name) { | ||
| if (unmangleable[name]) return false; | ||
| if (unmangleable.has(name)) return false; | ||
| if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false; | ||
@@ -226,10 +226,10 @@ return true; | ||
| function should_mangle(name) { | ||
| if (reserved[name]) return false; | ||
| if (reserved.has(name)) return false; | ||
| if (regex && !regex.test(name)) return false; | ||
| return cache.has(name) || names_to_mangle[name]; | ||
| return cache.has(name) || names_to_mangle.has(name); | ||
| } | ||
| function add(name) { | ||
| if (can_mangle(name)) names_to_mangle[name] = true; | ||
| if (!should_mangle(name)) unmangleable[name] = true; | ||
| if (can_mangle(name)) names_to_mangle.set(name, true); | ||
| if (!should_mangle(name)) unmangleable.set(name, true); | ||
| } | ||
@@ -236,0 +236,0 @@ |
+29
-21
@@ -47,5 +47,5 @@ /*********************************************************************** | ||
| function SymbolDef(id, scope, orig, init) { | ||
| this._bits = 0; | ||
| this.defun = undefined; | ||
| this.eliminated = 0; | ||
| this.exported = false; | ||
| this.global = false; | ||
| this.id = id; | ||
@@ -58,4 +58,4 @@ this.init = init; | ||
| this.replaced = 0; | ||
| this.safe_ids = undefined; | ||
| this.scope = scope; | ||
| this.undeclared = false; | ||
| } | ||
@@ -109,2 +109,11 @@ | ||
| DEF_BITPROPS(SymbolDef, [ | ||
| "const_redefs", | ||
| "cross_loop", | ||
| "direct_access", | ||
| "exported", | ||
| "global", | ||
| "undeclared", | ||
| ]); | ||
| var unary_side_effects = makePredicate("delete ++ --"); | ||
@@ -369,3 +378,3 @@ | ||
| if (!redefine(node, node.scope.parent_scope.resolve())) { | ||
| delete def.defun; | ||
| def.defun = undefined; | ||
| } else if (typeof node.thedef.init !== "undefined") { | ||
@@ -472,3 +481,3 @@ node.thedef.init = false; | ||
| if (!options) { | ||
| delete s._var_names; | ||
| s._var_names = undefined; | ||
| } else if (options.keep_fnames) { | ||
@@ -518,8 +527,8 @@ s.functions.each(function(d) { | ||
| scope.cname_holes = []; | ||
| scope.names_in_use = names = Object.create(null); | ||
| scope.names_in_use = names = new Dictionary(); | ||
| var cache = options.cache && options.cache.props; | ||
| scope.enclosed.forEach(function(def) { | ||
| if (def.unmangleable(options)) names[def.name] = true; | ||
| if (def.unmangleable(options)) names.set(def.name, true); | ||
| if (def.global && cache && cache.has(def.name)) { | ||
| names[cache.get(def.name)] = true; | ||
| names.set(cache.get(def.name), true); | ||
| } | ||
@@ -535,3 +544,3 @@ }); | ||
| var holes = scope.cname_holes; | ||
| var names = Object.create(null); | ||
| var names = new Dictionary(); | ||
| var scopes = [ scope ]; | ||
@@ -541,8 +550,7 @@ def.forEach(function(sym) { | ||
| do { | ||
| if (scopes.indexOf(scope) < 0) { | ||
| for (var name in names_in_use(scope, options)) { | ||
| names[name] = true; | ||
| } | ||
| scopes.push(scope); | ||
| } else break; | ||
| if (member(scope, scopes)) break; | ||
| names_in_use(scope, options).each(function(marker, name) { | ||
| names.set(name, marker); | ||
| }); | ||
| scopes.push(scope); | ||
| } while (scope = scope.parent_scope); | ||
@@ -553,5 +561,5 @@ }); | ||
| name = base54(holes[i]); | ||
| if (names[name]) continue; | ||
| if (names.has(name)) continue; | ||
| holes.splice(i, 1); | ||
| in_use[name] = true; | ||
| in_use.set(name, true); | ||
| return name; | ||
@@ -561,7 +569,7 @@ } | ||
| name = base54(++scope.cname); | ||
| if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue; | ||
| if (!names[name]) break; | ||
| if (in_use.has(name) || RESERVED_WORDS[name] || options.reserved.has[name]) continue; | ||
| if (!names.has(name)) break; | ||
| holes.push(scope.cname); | ||
| } | ||
| in_use[name] = true; | ||
| in_use.set(name, true); | ||
| return name; | ||
@@ -611,3 +619,3 @@ } | ||
| options.cache.props.each(function(mangled_name) { | ||
| mangled_names[mangled_name] = true; | ||
| mangled_names.set(mangled_name, true); | ||
| }); | ||
@@ -614,0 +622,0 @@ } |
+11
-9
@@ -80,10 +80,12 @@ /*********************************************************************** | ||
| function create_array_map() { | ||
| var map = Object.create(null); | ||
| var map = new Dictionary(); | ||
| var array = []; | ||
| array.index = function(name) { | ||
| if (!HOP(map, name)) { | ||
| map[name] = array.length; | ||
| var index = map.get(name); | ||
| if (!(index >= 0)) { | ||
| index = array.length; | ||
| array.push(name); | ||
| map.set(name, index); | ||
| } | ||
| return map[name]; | ||
| return index; | ||
| }; | ||
@@ -95,3 +97,3 @@ return array; | ||
| var sources = create_array_map(); | ||
| var sources_content = options.includeSources && Object.create(null); | ||
| var sources_content = options.includeSources && new Dictionary(); | ||
| var names = create_array_map(); | ||
@@ -115,3 +117,3 @@ var mappings = ""; | ||
| var content = map.sourcesContent[i]; | ||
| if (content) sources_content[map.sources[i]] = content; | ||
| if (content) sources_content.set(map.sources[i], content); | ||
| } | ||
@@ -150,4 +152,4 @@ }); | ||
| setSourceContent: sources_content ? function(source, content) { | ||
| if (!(source in sources_content)) { | ||
| sources_content[source] = content; | ||
| if (!sources_content.has(source)) { | ||
| sources_content.set(source, content); | ||
| } | ||
@@ -162,3 +164,3 @@ } : noop, | ||
| sourcesContent: sources_content ? sources.map(function(source) { | ||
| return sources_content[source] || null; | ||
| return sources_content.get(source) || null; | ||
| }) : undefined, | ||
@@ -165,0 +167,0 @@ names: names, |
+59
-33
@@ -99,11 +99,2 @@ /*********************************************************************** | ||
| function merge(obj, ext) { | ||
| var count = 0; | ||
| for (var i in ext) if (HOP(ext, i)) { | ||
| obj[i] = ext[i]; | ||
| count++; | ||
| } | ||
| return count; | ||
| } | ||
| function noop() {} | ||
@@ -175,14 +166,17 @@ function return_false() { return false; } | ||
| function Dictionary() { | ||
| this._values = Object.create(null); | ||
| this._size = 0; | ||
| this.values = Object.create(null); | ||
| } | ||
| Dictionary.prototype = { | ||
| set: function(key, val) { | ||
| if (!this.has(key)) ++this._size; | ||
| this._values["$" + key] = val; | ||
| if (key == "__proto__") { | ||
| this.proto_value = val; | ||
| } else { | ||
| this.values[key] = val; | ||
| } | ||
| return this; | ||
| }, | ||
| add: function(key, val) { | ||
| if (this.has(key)) { | ||
| this.get(key).push(val); | ||
| var list = this.get(key); | ||
| if (list) { | ||
| list.push(val); | ||
| } else { | ||
@@ -193,28 +187,35 @@ this.set(key, [ val ]); | ||
| }, | ||
| get: function(key) { return this._values["$" + key] }, | ||
| get: function(key) { | ||
| return key == "__proto__" ? this.proto_value : this.values[key]; | ||
| }, | ||
| del: function(key) { | ||
| if (this.has(key)) { | ||
| --this._size; | ||
| delete this._values["$" + key]; | ||
| if (key == "__proto__") { | ||
| delete this.proto_value; | ||
| } else { | ||
| delete this.values[key]; | ||
| } | ||
| return this; | ||
| }, | ||
| has: function(key) { return ("$" + key) in this._values }, | ||
| has: function(key) { | ||
| return key == "__proto__" ? "proto_value" in this : key in this.values; | ||
| }, | ||
| all: function(predicate) { | ||
| for (var i in this._values) | ||
| if (!predicate(this._values[i], i.substr(1))) | ||
| return false; | ||
| for (var i in this.values) | ||
| if (!predicate(this.values[i], i)) return false; | ||
| if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false; | ||
| return true; | ||
| }, | ||
| each: function(f) { | ||
| for (var i in this._values) | ||
| f(this._values[i], i.substr(1)); | ||
| for (var i in this.values) | ||
| f(this.values[i], i); | ||
| if ("proto_value" in this) f(this.proto_value, "__proto__"); | ||
| }, | ||
| size: function() { | ||
| return this._size; | ||
| return Object.keys(this.values).length + ("proto_value" in this); | ||
| }, | ||
| map: function(f) { | ||
| var ret = []; | ||
| for (var i in this._values) | ||
| ret.push(f(this._values[i], i.substr(1))); | ||
| for (var i in this.values) | ||
| ret.push(f(this.values[i], i)); | ||
| if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__")); | ||
| return ret; | ||
@@ -224,12 +225,19 @@ }, | ||
| var ret = new Dictionary(); | ||
| for (var i in this._values) | ||
| ret._values[i] = this._values[i]; | ||
| ret._size = this._size; | ||
| this.each(function(value, i) { | ||
| ret.set(i, value); | ||
| }); | ||
| return ret; | ||
| }, | ||
| toObject: function() { return this._values } | ||
| toObject: function() { | ||
| var obj = {}; | ||
| this.each(function(value, i) { | ||
| obj["$" + i] = value; | ||
| }); | ||
| return obj; | ||
| }, | ||
| }; | ||
| Dictionary.fromObject = function(obj) { | ||
| var dict = new Dictionary(); | ||
| dict._size = merge(dict._values, obj); | ||
| for (var i in obj) | ||
| if (HOP(obj, i)) dict.set(i.slice(1), obj[i]); | ||
| return dict; | ||
@@ -272,1 +280,19 @@ }; | ||
| } | ||
| function DEF_BITPROPS(ctor, props) { | ||
| if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", ")); | ||
| props.forEach(function(name, pos) { | ||
| var mask = 1 << pos; | ||
| Object.defineProperty(ctor.prototype, name, { | ||
| get: function() { | ||
| return !!(this._bits & mask); | ||
| }, | ||
| set: function(val) { | ||
| if (val) | ||
| this._bits |= mask; | ||
| else | ||
| this._bits &= ~mask; | ||
| }, | ||
| }); | ||
| }); | ||
| } |
+1
-1
@@ -6,3 +6,3 @@ { | ||
| "license": "BSD-2-Clause", | ||
| "version": "3.14.4", | ||
| "version": "3.14.5", | ||
| "engines": { | ||
@@ -9,0 +9,0 @@ "node": ">=0.8.0" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
1188776
0.24%30074
0.35%