Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #17096 > unrolled thread

eval - how to

Started byCezary Tomczyk <cezary.tomczyk@gmail.com>
First post2012-11-09 12:47 +0100
Last post2012-11-10 04:16 +0100
Articles 20 on this page of 28 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 12:47 +0100
    Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-09 05:53 -0800
      Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 22:28 +0100
        Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 10:23 +0100
        Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 11:15 +0100
          Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-11 00:35 +0100
            Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 20:34 +0100
      Re: eval - how to Dr J R Stockton <reply1245@merlyn.demon.co.uk.invalid> - 2012-11-10 22:42 +0000
    Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-09 17:46 +0100
      Re: eval - how to Tim Streater <timstreater@greenbee.net> - 2012-11-09 17:00 +0000
        Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-09 18:19 +0100
      Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-09 22:49 +0100
        Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-09 16:40 -0800
          Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 11:36 +0100
            Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 13:29 +0100
              Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 13:55 +0100
                Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 14:17 +0100
                  Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 20:50 +0100
                    Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-10 22:54 +0100
                      Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 15:22 +0100
                        Re: eval - how to Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-11-11 16:24 +0100
                          Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 19:23 +0100
            Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-11 10:40 -0800
              Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 20:41 +0100
                Re: eval - how to Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-11-11 13:34 -0800
                  Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-11 23:03 +0100
        Re: eval - how to Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-11-10 10:21 +0100
    Re: eval - how to SAM <stephanemoriaux.NoAdmin@wanadoo.fr.invalid> - 2012-11-10 04:16 +0100

Page 1 of 2  [1] 2  Next page →


#17096 — eval - how to

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-09 12:47 +0100
Subjecteval - how to
Message-ID<k7iqg9$n49$1@speranza.aioe.org>
According to "Better not use eval() because ... ":

How to use eval in a correct way?

For example when I'll get the JavaScript (or any other EcmaScript 
implementation) code through XMLHttpRequest then how to safely eval the 
code?

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [next] | [standalone]


#17097

FromAsen Bozhilov <asen.bozhilov@gmail.com>
Date2012-11-09 05:53 -0800
Message-ID<ad4ffcf9-f94f-44c4-b425-7310b78e92bb@m13g2000vbd.googlegroups.com>
In reply to#17096
Cezary Tomczyk wrote:
> According to "Better not use eval() because ... ":
>
> How to use eval in a correct way?
>
> For example when I'll get the JavaScript (or any other EcmaScript
> implementation) code through XMLHttpRequest then how to safely eval the
> code?

Your question skips your intentions of using `eval'. Without them, it
is almost impossible to tell you what is the correct way to use
`eval`. Now every usage of `eval` seems wrong. You should be more
concrete about it.
The problem with the `eval` except the performance is that it uses the
Variable Object of the calling execution context during variable
instantiation. It is easy to shot you in your foot in other words. In
regular ECMAScript3 environment you can use:

(function () {
    eval(code);
})();

It creates new execution context with separate variable object from
the surrounding execution context. Now the variable instantiation of
the eval is safer. It works exactly how ES5 strict-mode eval works. In
ES5 strict-mode, direct call of `eval` will create new Lexical
Environment which is used for the variables in eval code. Of course it
is still the problem that code passed to eval, could alter existing
variable in the scope chain or some global variables. In case you want
to truncate the scope chain for the `eval` call, you should not use
`eval` at all. Using Function constructor will do exactly that.
Function constructor never creates closure with the calling execution
context. Its internal [[Scope]] property always refers to Global
Object.

(function  () {
    var a = 10;
    Function('a = 20')();
    console.log(a); //10
})();
console.log(a); //20

First console.log output 10, which means the code passed to the
function is not able to alter the value of `a`. It is because the
function created by Function constructor does not form a closure with
surrounding function.
The second console.log, outputs 20, because in ES3 undeclared
variables "leak" to the Global Object. In ECMAScript 5 strict-mode all
the variables should be declared otherwise it is ReferenceError when
you try to assign a value to undeclared variable.

There is other story of undirected `eval` in ECMAScript 5.

(function  () {
    var ev = eval, //Store a reference to built-in eval
        a = 10;
    ev('var a = 20');
    console.log(a); //10
})();
console.log(a); //20

Now you would expect that calling `ev` the passed code will use the
Variable Object of the calling execution context, but this is not
true. This is because that is indirect calling of `eval`. According
ECMAScript5 10.4.2 Entering Eval Code, the indirect calls of the eval,
will evaluate the passed code, as it was a code in global execution
context. In other words the code will use the Global Object for its
variable and function declaration.

But indeed, you should write your intention to use eval and probably
there would be better responses.

[toc] | [prev] | [next] | [standalone]


#17105

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-09 22:28 +0100
Message-ID<k7jsi7$h6a$1@speranza.aioe.org>
In reply to#17097
W dniu 2012-11-09 14:53, Asen Bozhilov pisze:
> Cezary Tomczyk wrote:
>> According to "Better not use eval() because ... ":
>>
>> How to use eval in a correct way?
>>
>> For example when I'll get the JavaScript (or any other EcmaScript
>> implementation) code through XMLHttpRequest then how to safely eval the
>> code?
>
> Your question skips your intentions of using `eval'. Without them, it
> is almost impossible to tell you what is the correct way to use
> `eval`. Now every usage of `eval` seems wrong. You should be more
> concrete about it.

Right. I would like to get data from server using XMLHttpRequest and 
then, based on header from server response and data type, parse and run 
JavaScript code.

> The problem with the `eval` except the performance is that it uses the
> Variable Object of the calling execution context during variable
> instantiation. It is easy to shot you in your foot in other words. In
> regular ECMAScript3 environment you can use:
>
> (function () {
>      eval(code);
> })();
>
> It creates new execution context with separate variable object from
> the surrounding execution context. Now the variable instantiation of
> the eval is safer. It works exactly how ES5 strict-mode eval works. In
> ES5 strict-mode, direct call of `eval` will create new Lexical
> Environment which is used for the variables in eval code. Of course it
> is still the problem that code passed to eval, could alter existing
> variable in the scope chain or some global variables. In case you want
> to truncate the scope chain for the `eval` call, you should not use
> `eval` at all. Using Function constructor will do exactly that.
> Function constructor never creates closure with the calling execution
> context. Its internal [[Scope]] property always refers to Global
> Object.
>
> (function  () {
>      var a = 10;
>      Function('a = 20')();
>      console.log(a); //10
> })();
> console.log(a); //20

Correct me if I am wrong, but if I will use closure around my methods 
and variables then they are not outside available. 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;
})();

(function  () {
  var a = 10;
  Function('a = 20; b = t; c = s;')();
   console.log(a,b,c); //10,50
  })();
console.log(a,b,c); //20,50

Then I've got from console "ReferenceError: s is not defined" which is 
expected by me.

But I am afraid that in real life I have to expose some variables and 
methods outside of closure. I mean, as a global variables or methods.

So, if we speaking about getting string from server (XMLHttpRequest) and 
execute code what exactly means that using eval is insecure? Or maybe I 
misunderstanding something. :-(

> First console.log output 10, which means the code passed to the
> function is not able to alter the value of `a`. It is because the
> function created by Function constructor does not form a closure with
> surrounding function.
> The second console.log, outputs 20, because in ES3 undeclared
> variables "leak" to the Global Object. In ECMAScript 5 strict-mode all
> the variables should be declared otherwise it is ReferenceError when
> you try to assign a value to undeclared variable.
>
> There is other story of undirected `eval` in ECMAScript 5.
>
> (function  () {
>      var ev = eval, //Store a reference to built-in eval
>          a = 10;
>      ev('var a = 20');
>      console.log(a); //10
> })();
> console.log(a); //20
>
> Now you would expect that calling `ev` the passed code will use the
> Variable Object of the calling execution context, but this is not
> true. This is because that is indirect calling of `eval`. According
> ECMAScript5 10.4.2 Entering Eval Code, the indirect calls of the eval,
> will evaluate the passed code, as it was a code in global execution
> context. In other words the code will use the Global Object for its
> variable and function declaration.

> But indeed, you should write your intention to use eval and probably
> there would be better responses.

The question is above.

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#17114

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-10 10:23 +0100
Message-ID<7380843.eiFL6tTcTp@PointedEars.de>
In reply to#17105
Cezary Tomczyk wrote:

> W dniu 2012-11-09 14:53, Asen Bozhilov pisze:
>> Cezary Tomczyk wrote:
>>> According to "Better not use eval() because ... ":
>>>
>>> How to use eval in a correct way?
>>>
>>> For example when I'll get the JavaScript (or any other EcmaScript
>>> implementation) code through XMLHttpRequest then how to safely eval the
>>> code?
>>
>> Your question skips your intentions of using `eval'. Without them, it
>> is almost impossible to tell you what is the correct way to use
>> `eval`. Now every usage of `eval` seems wrong. You should be more
>> concrete about it.
> 
> Right. I would like to get data from server using XMLHttpRequest and
> then, based on header from server response and data type, parse and run
> JavaScript code.

The recommended approaches depend on the data.


PointedEars
-- 
var bugRiddenCrashPronePieceOfJunk = (
    navigator.userAgent.indexOf('MSIE 5') != -1
    && navigator.userAgent.indexOf('Mac') != -1
)  // Plone, register_function.js:16

[toc] | [prev] | [next] | [standalone]


#17115

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-10 11:15 +0100
Message-ID<2836184.TlQAl5i4AK@PointedEars.de>
In reply to#17105
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 <----------------------------------------'

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.

> Then I've got from console "ReferenceError: s is not defined" which is
> expected by me.

Exactly, but your logic is flawed.
 
> 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.


PointedEars
-- 
    realism:    HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness:    XHTML 1.1 as application/xhtml+xml
                                                    -- Bjoern Hoehrmann

[toc] | [prev] | [next] | [standalone]


#17153

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-11 00:35 +0100
Message-ID<k7mocc$sec$1@speranza.aioe.org>
In reply to#17115
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/

[toc] | [prev] | [next] | [standalone]


#17175

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-11 20:34 +0100
Message-ID<13959659.DiaCrlo6tG@PointedEars.de>
In reply to#17153
Cezary Tomczyk wrote:

> W dniu 2012-11-10 11:15, Thomas 'PointedEars' Lahn pisze:
>> [73 lines]
> 
> Good way to present hot it works. Many times just a diagram is better
> than 1000 words.

And often less is more.

>> 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"?

AISB: Read the Specification first, only then the vendor documentation.  For 
the vendor is an implementor of the Specification, and might have gotten the 
Specification wrong.  It has happened before.

And keep in mind that MDN is a wiki.  Anyone (particularly non-Mozilla 
people) can write any nonsense there (but not for long, hopefully).  I know, 
for I had to correct some parts of MDN, or rather MDC (Mozilla Developer 
Center) as it was called at the time.

What they perhaps meant to say is that the [[Scope]] property of Function 
instances created with the Function constructor contains only the Global 
Object, as it is specified in the ECMAScript Language Specification, 5.1 
Edition, section 15.3.3.

> 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".

No, function code created this way is always executed "in window context" 
because the [[Scope]] property of the associated Function instance contains 
only the Global Object (or the Global Environment).
 
> Even more confuses.

Understandable, given that you are trying to comprehend a misleading, if not 
patently wrong explanation.

> 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.

No, per Specification the scope chain of such code contains the local 
Variable Object (or Local Environment) and the Global Object (or Global 
Environment):

| 15.3.1 The Function Constructor Called as a Function
| 
| When Function is called as a function rather than as a constructor, it
| creates and initialises a new Function object. Thus the function call
| Function(...) is equivalent to the object creation expression new
| Function(...) with the same arguments.
| 
| […]
| 15.3.2 The Function Constructor
| 
| When Function is called as part of a new expression, it is a constructor:
| it initialises the newly created object.
| 
| 15.3.2.1 new Function (p1, p2, ... , pn, body)
| 
| […]
|  9. If body is strict mode code (see 10.1.1) then let strict be true, else
|     let strict be false.
| 10. If strict is true, throw any exceptions specified in 13.1 that apply.
| 11. Return a new Function object created as specified in 13.2 passing P as
|     the FormalParameterListopt and body as the FunctionBody. Pass in the
|     Global Environment as the Scope parameter and strict as the Strict
|     flag.

| 13.2 Creating Function Objects
|
| Given an optional parameter list specified by FormalParameterList, a body
| specified by FunctionBody, a Lexical Environment specified by Scope, and a
| Boolean flag Strict, a Function object is constructed as follows:
| 
| […]
|  9. Set the [[Scope]] internal property of F to the value of Scope.
| […]
| 19. If Strict is true, then
|   a. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
|   b. Call the [[DefineOwnProperty]] internal method of F with arguments
|      "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
|      [[Enumerable]]: false, [[Configurable]]: false}, and false.
|   c. Call the [[DefineOwnProperty]] internal method of F with arguments
|      "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower,
|      [[Enumerable]]: false, [[Configurable]]: false}, and false.

No other provisions are made for strict mode there, but strict mode does not 
matter here.  You will notice that the [[Scope]] property is used when the 
function is called, to create a new lexical environment (section 10.4.3) 
that is used in identifier resolution as specified in section 10.3.1.

Therefore, a ReferenceError exception should have been thrown on 
`console.log(a);' in any case because `a' was neither declared in the 
(inner) function code nor was it an existing property on the Global Object 
(it is thrown in Chromium "22.0.1229.94 Built on Debian wheezy/sid, running 
on Debian 6.0.6 (161065)").  The assignment to `a', which should have thrown 
another ReferenceError because of strict mode, should not have been reached 
at all.

So you have probably observed an implementation bug here.  This would be 
unsurprising in a beta version such as Firefox 16.0.3 (apparently version 
16.0.2 is the currently stable version).  That said, the `Function' 
constructor has a long history of being erroneously implemented, and it 
should probably be avoided because of that.

I am getting (correctly) a ReferenceError with message "a is not defined" 
both with and without Firebug 1.9.2 in Iceweasel 10.0.10.  The behavior in 
Firefox 16.0.3 may be a SpiderMonkey regression.  But one wonders if this 
has happened because you have assigned to a global `a' property before 
running this code instead.
 
>>> Then I've got from console "ReferenceError: s is not defined" which is
>>> expected by me.
>>
>> Exactly, but your logic is flawed.
> 
> Perhaps,

No, that much is certain.  If you assign in function code to an identifier 
that was not declared in that code, there are three possible outcomes:

1. You are assigning to a property of the next object in the scope chain
   that has a property of that name.

2. If the function code is not strict code, you are augmenting the Global
   Object with a new enumerable, deletable, writable property.

3. If the function code is strict code, a ReferenceError exception is
   thrown.

So, as I said often before here and elsewhere, you should declare your 
identifiers.


PointedEars
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on a Web 
page appears to be yearning for the bad old days, before the Web, when you 
had very little chance of reading a document written on another computer, 
another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#17155

FromDr J R Stockton <reply1245@merlyn.demon.co.uk.invalid>
Date2012-11-10 22:42 +0000
Message-ID<QP3S4XOxhtnQFwxv@invalid.uk.co.demon.merlyn.invalid>
In reply to#17097
In comp.lang.javascript message <ad4ffcf9-f94f-44c4-b425-7310b78e92bb@m1
3g2000vbd.googlegroups.com>, Fri, 9 Nov 2012 05:53:37, Asen Bozhilov
<asen.bozhilov@gmail.com> posted:

>The problem with the `eval` except the performance is that it uses the
>Variable Object of the calling execution context during variable
>instantiation. It is easy to shot you in your foot in other words.

Not necessarily.  My site only supplies pages; it receives nothing.
Therefore, where I write eval(), it is the reader whose foot can be
shot.  If the reader writes   while(1) alert(2)   then that is his
problem.

-- 
 (c) John Stockton, nr London, UK.   E-mail, see Home Page.    Turnpike v6.05.
 Website  <http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
 PAS EXE etc. : <http://www.merlyn.demon.co.uk/programs/> - see in 00index.htm
 Dates - miscdate.htm estrdate.htm js-dates.htm pas-time.htm critdate.htm etc.

[toc] | [prev] | [next] | [standalone]


#17100

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-09 17:46 +0100
Message-ID<2261899.gBobAo4G4S@PointedEars.de>
In reply to#17096
Cezary Tomczyk wrote:

> According to "Better not use eval() because ... ":
> 
> How to use eval in a correct way?
> 
> For example when I'll get the JavaScript (or any other EcmaScript
> implementation) code through XMLHttpRequest then how to safely eval the
> code?

(It's _ECMAScript_, published by _Ecma_ International, for historical 
reasons.)

The only way to safely use eval() is a) not to use it or b) to be sure that 
you are using a conforming implementation of ECMAScript Ed. 5 or later 
(where the scope chain of eval code is empty; which you really cannot be 
sure about in a browser). 

But if you really must use eval(), and want to/need to parse JSON(-like 
data) with it (instead of with JSON.parse()), be sure that the literal is 
evaluated in an expression context:

   var obj = eval("(" + JSON_object_string + ")");

The `(' and `)' would be necessary because the `{' and `}' of an object 
literal also delimit a Block statement, whose production takes precedence in 
a statement context.


PointedEars
-- 
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
  -- Richard Cornford, cljs, <cife6q$253$1$8300dec7@news.demon.co.uk> (2004)

[toc] | [prev] | [next] | [standalone]


#17101

FromTim Streater <timstreater@greenbee.net>
Date2012-11-09 17:00 +0000
Message-ID<timstreater-346A48.17002309112012@news.individual.net>
In reply to#17100
In article <2261899.gBobAo4G4S@PointedEars.de>,
 Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote:

> Cezary Tomczyk wrote:
> 
> > According to "Better not use eval() because ... ":
> > 
> > How to use eval in a correct way?
> > 
> > For example when I'll get the JavaScript (or any other EcmaScript
> > implementation) code through XMLHttpRequest then how to safely eval the
> > code?
> 
> (It's _ECMAScript_, published by _Ecma_ International, for historical 
> reasons.)

Yes, don't forget the underscores (_), everyone, they're most important.

-- 
Tim

"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted"  --  Bill of Rights 1689

[toc] | [prev] | [next] | [standalone]


#17102

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-09 18:19 +0100
Message-ID<3219900.xhZVmG0eJJ@PointedEars.de>
In reply to#17101
Tim Streater wrote:

>  Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote:
>> Cezary Tomczyk wrote:
>> > According to "Better not use eval() because ... ":
>> > 
>> > How to use eval in a correct way?
>> > 
>> > For example when I'll get the JavaScript (or any other EcmaScript
>> > implementation) code through XMLHttpRequest then how to safely eval the
>> > code?
>> (It's _ECMAScript_, published by _Ecma_ International, for historical
>> reasons.)
> 
> Yes, don't forget the underscores (_), everyone, they're most important.

Your inability to use a proper newsreader (and to quote properly) is your 
problem alone.


PointedEars
-- 
When all you know is jQuery, every problem looks $(olvable).

[toc] | [prev] | [next] | [standalone]


#17106

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-09 22:49 +0100
Message-ID<k7jtpr$jqo$1@speranza.aioe.org>
In reply to#17100
W dniu 2012-11-09 17:46, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> According to "Better not use eval() because ... ":
>>
>> How to use eval in a correct way?
>>
>> For example when I'll get the JavaScript (or any other EcmaScript
>> implementation) code through XMLHttpRequest then how to safely eval the
>> code?
>
> (It's _ECMAScript_, published by _Ecma_ International, for historical
> reasons.)

Ah, right.

> The only way to safely use eval() is a) not to use it or b) to be sure that
> you are using a conforming implementation of ECMAScript Ed. 5 or later
> (where the scope chain of eval code is empty; which you really cannot be
> sure about in a browser).
>
> But if you really must use eval(), and want to/need to parse JSON(-like
> data) with it (instead of with JSON.parse()), be sure that the literal is
> evaluated in an expression context:
>
>     var obj = eval("(" + JSON_object_string + ")");
>
> The `(' and `)' would be necessary because the `{' and `}' of an object
> literal also delimit a Block statement, whose production takes precedence in
> a statement context.

Ah, I maybe confused something and instead of thinking about safe 
parsing JSON string I thought about safe executing JavaScript code. Or 
maybe I should think about both of them.

As for parsing JSON string and according to what wrote Asen. Quick 
review of David Mark code bring me [1]:

[...]
  return function(s) { return (new Function('return (' + s + ')'))(); };
[...]

On the other hand, looked into the code 
https://github.com/douglascrockford/JSON-js/blob/master/json2.js [2] and 
I see much, much more complicated regexps and rest of code to check JSON 
string before its evaluated.

Now I am more confused than before. Why code [1] is so simple and code 
[2] is so complicated?

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#17111

FromAsen Bozhilov <asen.bozhilov@gmail.com>
Date2012-11-09 16:40 -0800
Message-ID<4265d7df-81e2-4c58-a16d-cafc435a1e88@j19g2000vba.googlegroups.com>
In reply to#17106
Cezary Tomczyk wrote:

> As for parsing JSON string and according to what wrote Asen. Quick
> review of David Mark code bring me [1]:
>
> [...]
>   return function(s) { return (new Function('return (' + s + ')'))(); };
> [...]

Obviously the JSON string comes from your server, otherwise the AJAX
call would fail to fetch the string duo to cross domain policy.
So the used approach according that is pretty safe. If you maintain
safe JSON strings, you should not care about the security at all. If
the strings come from the third parties, you could use the Crockford
approach.

> On the other hand, looked into the codehttps://github.com/douglascrockford/JSON-js/blob/master/json2.js[2] and
> I see much, much more complicated regexps and rest of code to check JSON
> string before its evaluated.
>
> Now I am more confused than before. Why code [1] is so simple and code
> [2] is so complicated?

He uses regexps to filter invalid tokens in the JSON string. If there
any invalid tokens the code throws a SyntaxError.
We have discussed it before in the group.

[toc] | [prev] | [next] | [standalone]


#17116

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-10 11:36 +0100
Message-ID<28208070.qZZrvzLHK0@PointedEars.de>
In reply to#17111
Asen Bozhilov wrote:

> Cezary Tomczyk wrote:
>> As for parsing JSON string and according to what wrote Asen. Quick
>> review of David Mark code bring me [1]:
>>
>> [...]
>> return function(s) { return (new Function('return (' + s + ')'))(); };
>> [...]
> 
> Obviously the JSON string comes from your server, otherwise the AJAX
> call would fail to fetch the string duo to cross domain policy.

First of all, it is the Same Origin Policy (SOP; *origin*, i. e. protocol, 
host, and port number must match).  That aside, this argument is no longer 
sound.  XHR can be made cross-domain if the target domain allows it.

<http://en.wikipedia.org/wiki/Same_origin_policy>

> So the used approach according that is pretty safe. If you maintain
> safe JSON strings, you should not care about the security at all. If
> the strings come from the third parties, you could use the Crockford
> approach.

Even if it was not a cross-origin request, there is no guarantee that the 
data are coming from the requested site.  You can work around the SOP 
yourself by setting up a transparent proxy for certain requests to your 
server, and there can still be a man-in-the-middle (MITM)-attack when you 
did not.
 
>> On the other hand, looked into the
>> codehttps://github.com/douglascrockford/JSON-js/blob/master/json2.js[2]
>> and I see much, much more complicated regexps and rest of code to check
>> JSON string before its evaluated.
>>
>> Now I am more confused than before. Why code [1] is so simple and code
>> [2] is so complicated?
> 
> He uses regexps to filter invalid tokens in the JSON string. If there
> any invalid tokens the code throws a SyntaxError.

Which is, of course, no longer necessary to do manually in many cases as 
that is what the built-in JSON.parse() does now.

> We have discussed it before in the group.

ACK.


PointedEars
-- 
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
  -- Richard Cornford, cljs, <cife6q$253$1$8300dec7@news.demon.co.uk> (2004)

[toc] | [prev] | [next] | [standalone]


#17118

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-10 13:29 +0100
Message-ID<k7lhbv$s7q$1@speranza.aioe.org>
In reply to#17116
W dniu 2012-11-10 11:36, Thomas 'PointedEars' Lahn pisze:
> Asen Bozhilov wrote:
>
>> Cezary Tomczyk wrote:
>>> As for parsing JSON string and according to what wrote Asen. Quick
>>> review of David Mark code bring me [1]:
>>>
>>> [...]
>>> return function(s) { return (new Function('return (' + s + ')'))(); };
>>> [...]
>>
>> Obviously the JSON string comes from your server, otherwise the AJAX
>> call would fail to fetch the string duo to cross domain policy.
>
> First of all, it is the Same Origin Policy (SOP; *origin*, i. e. protocol,
> host, and port number must match).  That aside, this argument is no longer
> sound.  XHR can be made cross-domain if the target domain allows it.
>
> <http://en.wikipedia.org/wiki/Same_origin_policy>

While CORS (Cross-Origin Resource Sharing) is implemented in most 
browsers then IE8 and IE9 do not support it. Source: 
http://caniuse.com/#search=cors
The workaround is to use iframe for them, right?

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#17119

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-10 13:55 +0100
Message-ID<4351338.UcPtXxdYxD@PointedEars.de>
In reply to#17118
Cezary Tomczyk wrote:

> W dniu 2012-11-10 11:36, Thomas 'PointedEars' Lahn pisze:
>> Asen Bozhilov wrote:
>>> Obviously the JSON string comes from your server, otherwise the AJAX
>>> call would fail to fetch the string duo to cross domain policy.
>>
>> First of all, it is the Same Origin Policy (SOP; *origin*, i. e.
>> protocol, host, and port number must match).  That aside, this argument
>> is no longer sound.  XHR can be made cross-domain if the target domain
>> allows it.
>>
>> <http://en.wikipedia.org/wiki/Same_origin_policy>
> 
> While CORS (Cross-Origin Resource Sharing) is implemented in most
> browsers then IE8 and IE9 do not support it. Source:
> http://caniuse.com/#search=cors

There is another source that says they do:

<https://developer.mozilla.org/en-US/docs/HTTP_access_control>

> The workaround is to use iframe for them, right?

Not necessarily.


PointedEars
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#17120

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-10 14:17 +0100
Message-ID<k7lk58$3m1$1@speranza.aioe.org>
In reply to#17119
W dniu 2012-11-10 13:55, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2012-11-10 11:36, Thomas 'PointedEars' Lahn pisze:
>>> Asen Bozhilov wrote:
>>>> Obviously the JSON string comes from your server, otherwise the AJAX
>>>> call would fail to fetch the string duo to cross domain policy.
>>>
>>> First of all, it is the Same Origin Policy (SOP; *origin*, i. e.
>>> protocol, host, and port number must match).  That aside, this argument
>>> is no longer sound.  XHR can be made cross-domain if the target domain
>>> allows it.
>>>
>>> <http://en.wikipedia.org/wiki/Same_origin_policy>
>>
>> While CORS (Cross-Origin Resource Sharing) is implemented in most
>> browsers then IE8 and IE9 do not support it. Source:
>> http://caniuse.com/#search=cors
>
> There is another source that says they do:
>
> <https://developer.mozilla.org/en-US/docs/HTTP_access_control>

Ah, yes. I forgot about XDomainRequest. "caniuse" site should update 
information about that.

>> The workaround is to use iframe for them, right?
>
> Not necessarily.

Well, then what to use for IE7? When not iframe.

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#17151

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-10 20:50 +0100
Message-ID<1870325.DxoWjsJ0Ul@PointedEars.de>
In reply to#17120
Cezary Tomczyk wrote:

> W dniu 2012-11-10 13:55, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> W dniu 2012-11-10 11:36, Thomas 'PointedEars' Lahn pisze:
>>>> Asen Bozhilov wrote:
>>>>> Obviously the JSON string comes from your server, otherwise the AJAX
>>>>> call would fail to fetch the string duo to cross domain policy.
>>>>
>>>> First of all, it is the Same Origin Policy (SOP; *origin*, i. e.
>>>> protocol, host, and port number must match).  That aside, this argument
>>>> is no longer sound.  XHR can be made cross-domain if the target domain
>>>> allows it.
>>>>
>>>> <http://en.wikipedia.org/wiki/Same_origin_policy>
>>>
>>> While CORS (Cross-Origin Resource Sharing) is implemented in most
>>> browsers then IE8 and IE9 do not support it. Source:
>>> http://caniuse.com/#search=cors
> […]
>>> The workaround is to use iframe for them, right?
>>
>> Not necessarily.
> 
> Well, then what to use for IE7? When not iframe.

You can use a transparent proxy with or without a JSONP-like approach for 
cross-domain requests in all user agents that would parse the content of new 
`script' elements, including Internet Explorer before version 10 (perhaps 
down to version 4 inclusive; proper tests are pending), without iframes.  
The advantage of JSONP is that you can be sure the data is loaded when the 
callback is called.

BTW, iframe cross-domain scripting requires a proper `X-Frame-Options' 
response header field value in case document.domain is not applicable.


PointedEars
-- 
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
  -- Richard Cornford, comp.lang.javascript, 2011-11-14

[toc] | [prev] | [next] | [standalone]


#17152

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2012-11-10 22:54 +0100
Message-ID<k7mieq$f4l$1@speranza.aioe.org>
In reply to#17151
W dniu 2012-11-10 20:50, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2012-11-10 13:55, Thomas 'PointedEars' Lahn pisze:
>>> Cezary Tomczyk wrote:
>>>> W dniu 2012-11-10 11:36, Thomas 'PointedEars' Lahn pisze:
>>>>> Asen Bozhilov wrote:
>>>>>> Obviously the JSON string comes from your server, otherwise the AJAX
>>>>>> call would fail to fetch the string duo to cross domain policy.
>>>>>
>>>>> First of all, it is the Same Origin Policy (SOP; *origin*, i. e.
>>>>> protocol, host, and port number must match).  That aside, this argument
>>>>> is no longer sound.  XHR can be made cross-domain if the target domain
>>>>> allows it.
>>>>>
>>>>> <http://en.wikipedia.org/wiki/Same_origin_policy>
>>>>
>>>> While CORS (Cross-Origin Resource Sharing) is implemented in most
>>>> browsers then IE8 and IE9 do not support it. Source:
>>>> http://caniuse.com/#search=cors
>> […]
>>>> The workaround is to use iframe for them, right?
>>>
>>> Not necessarily.
>>
>> Well, then what to use for IE7? When not iframe.
>
> You can use a transparent proxy with or without a JSONP-like approach for
> cross-domain requests in all user agents that would parse the content of new
> `script' elements, including Internet Explorer before version 10 (perhaps
> down to version 4 inclusive; proper tests are pending), without iframes.
> The advantage of JSONP is that you can be sure the data is loaded when the
> callback is called.

Makes sense. Now I need to read more about possible security issues. 
Just in any case.

> BTW, iframe cross-domain scripting requires a proper `X-Frame-Options'
> response header field value in case document.domain is not applicable.

Which mostly should not be a problem to set this header.

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#17163

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-11-11 15:22 +0100
Message-ID<5115212.H4Pzn9t7sn@PointedEars.de>
In reply to#17152
Cezary Tomczyk wrote:

> W dniu 2012-11-10 20:50, Thomas 'PointedEars' Lahn pisze:
>> BTW, iframe cross-domain scripting requires a proper `X-Frame-Options'
>> response header field value in case document.domain is not applicable.
> 
> Which mostly should not be a problem to set this header.

How so?

Please trim your quotes to the relevant minimum.


PointedEars
-- 
Sometimes, what you learn is wrong. If those wrong ideas are close to the 
root of the knowledge tree you build on a particular subject, pruning the 
bad branches can sometimes cause the whole tree to collapse.
  -- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom@94.75.214.39>

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.javascript


csiph-web