Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an eval access external functions?

My company allows us to write code in a javascript editor online. Other libraries are preloaded, so the code we write has access to these libraries.

Specifically, we can use Underscore.js and jQuery.js functions in our code. We can also use our very own library Graphie.js.

In an effort to save myself time, I have slowly built up my own personal set of functions which I copy and paste into every code I write. That set of functions is now so long that I want to fetch it externally (in order to save space, etc).

$.getScript( 'url/to/myfunctions.js' )

I tried the above code, but it was too good to be true. This jQuery function getScript seems to run myfunctions as their own independent unit. This fails because myfunctions use our Graphie.js functions within them.

$.get( 'url/to/myfunctions', eval )

This above code fetches and successfully evals my code (i configured my server to do so). Also too good to be true. Any jQuery and Underscode functions in my code actually work. But any Graphie functions in my code cause an error.

like image 522
mareoraft Avatar asked Sep 06 '26 00:09

mareoraft


1 Answers

Instead of

$.get( 'url/to/myfunctions', eval );

try

$.get( 'url/to/myfunctions', function(code) { eval(code); } );

This way the eval function is going to be executed within the same scope as the rest of your code, rather than within the scope of jQuery. After the code has been fetched and executed, you can continue with the execution of the rest of your code:

$.get( 'url/to/myfunctions', function(code) {
  eval(code);
  callback();
});

function callback() {
  // Your code goes here
}

Explanation

For the purpose of the explanation, let's use this simplified model of the environment, in which your code is being executed:

// JQuery is defined in the global scope
var $ = {
  get: function( url, fn ) {
    var responses = {
      "url/to/myfunctions": "try {\
        if(graphie) log('Graphie is visible.');\
      } catch (e) {\
        log('Graphie is not visible. (' + e + ')');\
      }"
    }; fn( responses[url] );
  }
};

(function() {
  // Graphie is defined in a local scope
  var graphie = {};
  (function() {
    // Your code goes here
    $.get( "url/to/myfunctions", eval );
    $.get( "url/to/myfunctions", function(code) { eval (code); } );
  })();
})();
The output: <ol id="output"></ol>
<script>
  function log(msg) {
    var el = document.createElement("li");
    el.appendChild(document.createTextNode(msg));
    output.appendChild(el);
  }
</script>

As you can see, the function passed to $.get gets executed inside its body. If you only pass eval to $.get, then you don't capture the local variable graphie, which is then invisible to the evaluated code. By wrapping eval inside an anonymous function, you capture the reference to the local variable graphie, which is then visible to the evaluated code.

like image 115
Witiko Avatar answered Sep 07 '26 15:09

Witiko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!