Socket
Socket
Sign inDemoInstall

terser

Package Overview
Dependencies
Maintainers
1
Versions
180
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

terser - npm Package Compare versions

Comparing version 5.16.2 to 5.16.3

4

CHANGELOG.md
# Changelog
## v5.16.3
- Ensure function definitions, don't assume the values of variables defined after them.
## v5.16.2

@@ -4,0 +8,0 @@

231

lib/compress/inline.js

@@ -95,3 +95,2 @@ /***********************************************************************

import "./reduce-vars.js";
import { is_lhs } from "./inference.js";
import {

@@ -118,2 +117,9 @@ SQUEEZED,

/**
* Module that contains the inlining logic.
*
* @module
*
* The stars of the show are `inline_into_symbolref` and `inline_into_call`.
*/

@@ -149,132 +155,131 @@ function within_array_or_object_literal(compressor) {

const parent = compressor.parent();
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
const def = self.definition();
const nearest_scope = compressor.find_scope();
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
def.fixed = false;
def.single_use = false;
return self;
const def = self.definition();
const nearest_scope = compressor.find_scope();
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
def.fixed = false;
def.single_use = false;
return self;
}
let fixed = self.fixed_value();
let single_use = def.single_use
&& !(parent instanceof AST_Call
&& (parent.is_callee_pure(compressor))
|| has_annotation(parent, _NOINLINE))
&& !(parent instanceof AST_Export
&& fixed instanceof AST_Lambda
&& fixed.name);
if (single_use && fixed instanceof AST_Node) {
single_use =
!fixed.has_side_effects(compressor)
&& !fixed.may_throw(compressor);
}
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
if (retain_top_func(fixed, compressor)) {
single_use = false;
} else if (def.scope !== self.scope
&& (def.escaped == 1
|| has_flag(fixed, INLINED)
|| within_array_or_object_literal(compressor)
|| !compressor.option("reduce_funcs"))) {
single_use = false;
} else if (is_recursive_ref(compressor, def)) {
single_use = false;
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
single_use = fixed.is_constant_expression(self.scope);
if (single_use == "f") {
var scope = self.scope;
do {
if (scope instanceof AST_Defun || is_func_expr(scope)) {
set_flag(scope, INLINED);
}
} while (scope = scope.parent_scope);
}
}
}
let fixed = self.fixed_value();
let single_use = def.single_use
&& !(parent instanceof AST_Call
&& (parent.is_callee_pure(compressor))
|| has_annotation(parent, _NOINLINE))
&& !(parent instanceof AST_Export
&& fixed instanceof AST_Lambda
&& fixed.name);
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
single_use =
def.scope === self.scope
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|| parent instanceof AST_Call
&& parent.expression === self
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
}
if (single_use && fixed instanceof AST_Node) {
single_use =
!fixed.has_side_effects(compressor)
&& !fixed.may_throw(compressor);
if (single_use && fixed) {
if (fixed instanceof AST_DefClass) {
set_flag(fixed, SQUEEZED);
fixed = make_node(AST_ClassExpression, fixed, fixed);
}
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
if (retain_top_func(fixed, compressor)) {
single_use = false;
} else if (def.scope !== self.scope
&& (def.escaped == 1
|| has_flag(fixed, INLINED)
|| within_array_or_object_literal(compressor)
|| !compressor.option("reduce_funcs"))) {
single_use = false;
} else if (is_recursive_ref(compressor, def)) {
single_use = false;
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
single_use = fixed.is_constant_expression(self.scope);
if (single_use == "f") {
var scope = self.scope;
do {
if (scope instanceof AST_Defun || is_func_expr(scope)) {
set_flag(scope, INLINED);
}
} while (scope = scope.parent_scope);
if (fixed instanceof AST_Defun) {
set_flag(fixed, SQUEEZED);
fixed = make_node(AST_Function, fixed, fixed);
}
if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
const defun_def = fixed.name.definition();
let lambda_def = fixed.variables.get(fixed.name.name);
let name = lambda_def && lambda_def.orig[0];
if (!(name instanceof AST_SymbolLambda)) {
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
name.scope = fixed;
fixed.name = name;
lambda_def = fixed.def_function(name);
}
walk(fixed, node => {
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
node.thedef = lambda_def;
lambda_def.references.push(node);
}
}
});
}
if (
(fixed instanceof AST_Lambda || fixed instanceof AST_Class)
&& fixed.parent_scope !== nearest_scope
) {
fixed = fixed.clone(true, compressor.get_toplevel());
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
single_use =
def.scope === self.scope
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|| parent instanceof AST_Call
&& parent.expression === self
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
nearest_scope.add_child_scope(fixed);
}
return fixed.optimize(compressor);
}
if (single_use && fixed) {
if (fixed instanceof AST_DefClass) {
set_flag(fixed, SQUEEZED);
fixed = make_node(AST_ClassExpression, fixed, fixed);
// multiple uses
if (fixed) {
let replace;
if (fixed instanceof AST_This) {
if (!(def.orig[0] instanceof AST_SymbolFunarg)
&& def.references.every((ref) =>
def.scope === ref.scope
)) {
replace = fixed;
}
if (fixed instanceof AST_Defun) {
set_flag(fixed, SQUEEZED);
fixed = make_node(AST_Function, fixed, fixed);
}
if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
const defun_def = fixed.name.definition();
let lambda_def = fixed.variables.get(fixed.name.name);
let name = lambda_def && lambda_def.orig[0];
if (!(name instanceof AST_SymbolLambda)) {
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
name.scope = fixed;
fixed.name = name;
lambda_def = fixed.def_function(name);
}
walk(fixed, node => {
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
node.thedef = lambda_def;
lambda_def.references.push(node);
}
});
}
} else {
var ev = fixed.evaluate(compressor);
if (
(fixed instanceof AST_Lambda || fixed instanceof AST_Class)
&& fixed.parent_scope !== nearest_scope
ev !== fixed
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
) {
fixed = fixed.clone(true, compressor.get_toplevel());
nearest_scope.add_child_scope(fixed);
replace = make_node_from_constant(ev, fixed);
}
return fixed.optimize(compressor);
}
// multiple uses
if (fixed) {
let replace;
if (replace) {
const name_length = self.size(compressor);
const replace_size = replace.size(compressor);
if (fixed instanceof AST_This) {
if (!(def.orig[0] instanceof AST_SymbolFunarg)
&& def.references.every((ref) =>
def.scope === ref.scope
)) {
replace = fixed;
}
} else {
var ev = fixed.evaluate(compressor);
if (
ev !== fixed
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
) {
replace = make_node_from_constant(ev, fixed);
}
let overhead = 0;
if (compressor.option("unused") && !compressor.exposed(def)) {
overhead =
(name_length + 2 + replace_size) /
(def.references.length - def.assignments);
}
if (replace) {
const name_length = self.size(compressor);
const replace_size = replace.size(compressor);
let overhead = 0;
if (compressor.option("unused") && !compressor.exposed(def)) {
overhead =
(name_length + 2 + replace_size) /
(def.references.length - def.assignments);
}
if (replace_size <= name_length + overhead) {
return replace;
}
if (replace_size <= name_length + overhead) {
return replace;
}

@@ -281,0 +286,0 @@ }

@@ -106,5 +106,6 @@ /***********************************************************************

// Define the method AST_Node#reduce_vars, which goes through the AST in
// execution order to perform basic flow analysis
/**
* Define the method AST_Node#reduce_vars, which goes through the AST in
* execution order to perform basic flow analysis
*/
function def_reduce_vars(node, func) {

@@ -116,2 +117,3 @@ node.DEFMETHOD("reduce_vars", func);

/** Clear definition properties */
function reset_def(compressor, def) {

@@ -125,3 +127,6 @@ def.assignments = 0;

def.single_use = undefined;
if (def.scope.pinned()) {
if (
def.scope.pinned()
|| (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
) {
def.fixed = false;

@@ -448,11 +453,19 @@ } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {

clear_flag(this, INLINED);
push(tw);
// Sometimes we detach the lambda for safety, and instead of push()
// we go to an entirely fresh lineage of safe_ids.
let previous_safe_ids;
if (this instanceof AST_Defun || this.uses_arguments || this.pinned()) {
previous_safe_ids = tw.safe_ids;
tw.safe_ids = Object.create(null);
} else {
push(tw);
}
reset_variables(tw, compressor, this);
if (this.uses_arguments) {
descend();
pop(tw);
return;
}
var iife;
if (!this.name
&& !this.uses_arguments
&& !this.pinned()
&& (iife = tw.parent()) instanceof AST_Call

@@ -483,3 +496,9 @@ && iife.expression === this

descend();
pop(tw);
if (previous_safe_ids) {
tw.safe_ids = previous_safe_ids;
} else {
pop(tw);
}
return true;

@@ -486,0 +505,0 @@ }

@@ -7,3 +7,3 @@ {

"license": "BSD-2-Clause",
"version": "5.16.2",
"version": "5.16.3",
"engines": {

@@ -10,0 +10,0 @@ "node": ">=10"

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc