Uglifyjs: Reference Error in recursion

Created on 16 Jan 2018  路  2Comments  路  Source: mishoo/UglifyJS

Bug report or feature request?

Bug

ES5 or ES6+ input?

ES5

Uglify version (uglifyjs -V)
tested 3.3.3 to 3.3.7
3.3.2 works
I think is related to this change #2628
JavaScript input

(function () {
  'use strict';
  window.ParseService = ParseService;
  function ParseService() {

    function scanObject(clone) {
      var keys = Object.keys(clone);
      var keysLength = keys.length - 1;

      for (keysLength; keysLength >= 0; keysLength--) {
        var key = keys[keysLength];
        // do some extra checks
        clone[key] = scanObject(clone[key]);
      }

      return clone;
    }

    function checkObject(originalObject) {
      // do some extra stuff
      return scanObject(originalObject);
    }

    return checkObject({
      a: 'abc',
      b: 'dor',
      c: [1, 2, 3]
    });
  }
})();

To able to reproduce the issue outside of the normal source code found that IIFE and checkObject function had to be present.

The uglifyjs CLI command executed or minify() options used.
uglifyjs input.js --compress --mangle --output output.js

JavaScript output or error produced.
ReferenceError: b is not defined

!function () {
  'use strict';
  window.ParseService = function () {
    return r = {
      a: 'abc',
      b: 'dor',
      c: [1, 2, 3]
    }, function (r) {  // <-- here function name should be `b`
      for (var n = Object.keys(r), e = n.length - 1; e >= 0; e--) {
        var t = n[e];
        r[t] = b(r[t]); // calling same function recursive
      }
      return r;
    }(r);
    var r;
  };
}();

bug

All 2 comments

Temporary bug workaround:

$ bin/uglifyjs -V
uglify-js 3.3.7
$ bin/uglifyjs input.js -m -c reduce_funcs=false -b
!function() {
    "use strict";
    window.ParseService = function() {
        function r(n) {
            for (var e = Object.keys(n), t = e.length - 1; t >= 0; t--) {
                var c = e[t];
                n[c] = r(n[c]);
            }
            return n;
        }
        return n = {
            a: "abc",
            b: "dor",
            c: [ 1, 2, 3 ]
        }, r(n);
        var n;
    };
}();

@tiberiuzuld thanks for the report - investigating.

Reduced test case:

console.log(function() {
    return f;
    function f(n) {
        function g(i) {
            return i && i + g(i - 1);
        }
        function h(j) {
            return g(j);
        }
        return h(n);
    }
}()(5));
$ cat test.js | node
15
$ uglifyjs test.js -bc | node
    return j = n, i = j, i && i + g(i - 1);
                              ^

ReferenceError: g is not defined
    at [stdin]:2:31
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexlamsl picture alexlamsl  路  5Comments

Jimbly picture Jimbly  路  4Comments

GrosSacASac picture GrosSacASac  路  3Comments

Havunen picture Havunen  路  5Comments

diegocr picture diegocr  路  3Comments