Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #17096 > unrolled thread
| Started by | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| First post | 2012-11-09 12:47 +0100 |
| Last post | 2012-11-10 04:16 +0100 |
| Articles | 20 on this page of 28 — 6 participants |
Back to article view | Back to comp.lang.javascript
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 →
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-11-09 12:47 +0100 |
| Subject | eval - 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]
| From | Asen Bozhilov <asen.bozhilov@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Dr J R Stockton <reply1245@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Tim Streater <timstreater@greenbee.net> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Asen Bozhilov <asen.bozhilov@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-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