Path: csiph.com!usenet.pasdenom.info!aioe.org!.POSTED!not-for-mail From: Cezary Tomczyk Newsgroups: comp.lang.javascript Subject: Re: eval - how to Date: Sun, 11 Nov 2012 00:35:41 +0100 Organization: Aioe.org NNTP Server Lines: 148 Message-ID: References: <2836184.TlQAl5i4AK@PointedEars.de> NNTP-Posting-Host: RMrsF+s1qSnxq5Qkkqjnpw.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121026 Thunderbird/16.0.2 X-Notice: Filtered by postfilter v. 0.8.2 Xref: csiph.com comp.lang.javascript:17153 W dniu 2012-11-10 11:15, Thomas 'PointedEars' Lahn pisze: > Cezary Tomczyk wrote: > >> W dniu 2012-11-09 14:53, Asen Bozhilov pisze: >> >> Correct me if I am wrong, but if I will use closure around my methods >> and variables then they are not outside available. > > Correct. > >> So, potentially bad code, which can be run using Function, have no access >> to my variables and methods, right? Example: >> >> var t = 50; >> >> (function(){ >> var s = 100; >> })(); > > That is a closure. > >> (function () { >> var a = 10; > > That is a closure. > >> Function('a = 20; b = t; c = s;')(); > > That is *not* a closure. The assignments are to (usually newly created) > properties of the Global Object … > >> console.log(a,b,c); //10,50 > > … so the local variables of the calling context (here: a) are not affected, > but the global ones (here: b, c) are. > >> })(); >> console.log(a,b,c); //20,50 > > QED. This code would throw a ReferenceError exception if the innermost > Function code was strict mode code: > > /* ReferenceError: a is not defined */ > Function('"use strict"; a = 20;')(); > > Perhaps a figure helps (use a fixed-width font). Assuming `t' is a global > variable: > > ,--------->----------. > : : > ,--------------------. : > : Global object : : > :--------------------. : > var t = 50; ----------------------------> t : number = 50 --->-. : > ,--------> a : number = 20 : : : > : ,------> b : number = 50 : : : > : : ,----> c : number = ? -------.-. : > : : : `--------------------' : : : : > : : : : : : : > (function(){ : : : ,--------------------. : : v : > var s = 100; ---------------:-:-:----> s : number = 100 : : : : : > })(); : : : `--------------------' : : : : > : : : : : : : > (function () { : : : ,-------------------. : : : : > var a = 10; -----------------:-:-:-----> a : number = 10 --->----. : > : : : `-------------------' : : : : > : : : : : : : > Function( : : : : : : : > 'a = 20;' ---------------' : : : : : : > + 'b = t;' ------------------'<----------------------------' : : : > + 'c = s;' --------------------'<----------------------------' : : > )(); : : > : : > console.log(a,b,c); //10,50 <------------------------------------' : > })(); : > : > console.log(a,b,c); //20,50 <----------------------------------------' Good way to present hot it works. Many times just a diagram is better than 1000 words. > In non-strict code, the error occurs where the `?' is. In strict code, the > error occurs earlier, where the second `a' is attempted to be assigned to. > For strict mode essentially forbids augmenting the Global Object (or any > other object in the scope chain outside the local execution context) by > simple assignment to an identifier in function or eval code. Hmm, something weird. "Note: Functions created with the Function constructor do not create closures to their creation contexts; they always run in the window context (unless the function body starts with a "use strict"; statement, in which case the context is undefined)." Source: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function "context is undefined"? If I run in console Firefox 16.0.2: var t = 50; (function () { var a = 10; Function('"use strict"; console.log(t); a = 20;')(); })(); then results of console is "50". As I understand Function is run in window context because t is "50" instead of "undefined". Even more confuses. Example: var t = 50; (function () { var a = 10; Function('"use strict"; console.log(a); a = 20;')(); })(); shows me in console result "20". I expected "a" with "10". I thought that scope chain is just inside Function and no more. >> Then I've got from console "ReferenceError: s is not defined" which is >> expected by me. > > Exactly, but your logic is flawed. Perhaps, but that's why I asking until I understand. >> So, if we speaking about getting string from server (XMLHttpRequest) and >> execute code what exactly means that using eval is insecure? > > Unless in ES 5+ strict mode, the scope chain of eval code is not empty. > Code can be injected into your program and use the capabilities of your > program. You would want only trustworthy code to do that, and there are no > guarantees. Besides, eval code is harder to debug. > > This can be useful; eval() can be used to hide potentially unsupported > program syntax. > > But if all you want to transfer is data, and not business logic, then you > should parse the data and you should not allow business logic to be > injected. Makes sense. Thanks for explanation. -- Cezary Tomczyk http://www.ctomczyk.pl/