On 11.04.2011 18:07, Mark S. Miller wrote:
On Sun, Apr 10, 2011 at 11:21 PM, David Herman <[email protected]
<mailto:[email protected]>> wrote:
I wondered if someone was going to make this point.
> That should be
>
> while (!{}.hasOwnProperty.call(obj, key))
>
> which works even if obj has an own property named 'hasOwnProperty'.
Not if someone mutates Object.prototype.hasOwnProperty or
Function.prototype.call. I don't think we need to polish a proof
of concept.
First, I agree that for the original purpose of this thread, this
polishing is irrelevant, so I have changed the subject. But your
counter-examples do help to highlight something I've been thinking
about. Because of such pervasive mutability, we really haven't had a
clear notion of "correctness" for JavaScript. For normal JavaScript
programs, if run after some other code has already mutated that
environment's primordials arbitrarily, there's so little they can
count on that very few programs could be written "correctly" under
these onerous assumptions[1]. For the notion of "correctness" in
JavaScript to be useful, I think we must allow JavaScript programs to
rely on the primordial at least continuing to obey their original
contract. However, the use of objects as maps from strings to values
is pervasive, e.g., in JSON unserialization, so we should not allow
general purpose JavaScript programs to rely on, for example,
'hasOwnProperty' not being overridden.
Retrofitting a reasonable theory of correctness after the fact is a
tricky exercise. The above theory represents a practical compromise
between the assumption that common programs make (primordials obey
their original contracts) vs. the assumptions that common programs
break (hasOwnProperty is not overridden). Thus, I claim that the
original program should not be considered "correct", while the
modified program should, despite the problematic cases raised by your
counter-example.
As I see it, you address the "issue" of unstratified meta-programming
(note, I take the "issue" in quotes, since there's no a single meaning
whether the unstratified meta-level is so bad).
It depends on how to look on the issue. On one hand, why if a user
changes the behavior of the `hasOwnProperty` of _his_ object in _his_
program, then the program should be considered as incorrect? The user
knows how to handle `hasOwnProperty` for the particular object and the
ability to override it is the ability to control unstratified meta-level
via simple reassigning to meta-hooks.
On the other hand, yes, since we have the ability to modify any JS code
via console or even via browser address bar (using pseudo-protocol
javascript:), then it can be viewed as the issue and as a security program.
But the salvation by the big deal should not be found in making a
dynamic language as a completely frozen and static, but in the
disallowing of code modification (code injection, code poisoning if you
will) via such a simple tools as the console or address bar.
Having the ability to inject the needed code via console just makes e.g.
browser scripting as just an _addition_ for the server code. This is in
case if we have combined client-server application. It's obvious, that
if we have some validation tool, then the validation on the client side
should be done only as the _convenient addition_. But the same
validation will be done on the server, since we understand that the
client code can be easily injected (the simplest example e.g.
utils.validate = function () { return true; } which always will return
positive result).
If we have only client-side application, then the user, if breaks some
code via injection just breaks his own page and therefore just refuses
the convenience we wanted to give him. He doesn't break anything besides
his own page.
So that's the language is dynamic and allow to change objects in runtime
is not in my view about "correctness" of a program. A programmer, having
control of his code, knows how and why he wants to augment and modify
his current runtime objects and code.
From this viewpoint I don't think we need to disallow modifying of
`hasOwnProperty` and similar. Better then to reuse ES5 approach and
separate this meta-operation to Object.hasOwnProperty(foo).
The fact that a language is static perhaps doesn't cancel the fact that
the code still can be injected, etc. So again, IMO a "correct program"
is not about "let's freeze everything here". And "predefined and
predicted contract" also relates to statics mostly. In "duck typing"
exactly this contract can be achieved during the runtime -- one line
before an object cannot pass the "duck-test", on the other line (after
some mutations) it already can do this, it satisfies the contract -- and
it's achieved not via statics in the language.
Dmitry.
[1] SES initialization freezes the primordials, so SES programs can
safely assume they are frozen. But the point I'm making here are not
specific to SES.
Dave
--
Cheers,
--MarkM
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss