mimicking __proto__ in Opera

Y

Yan Huang

Hi,

Firefox's JS engine implementation has a built-in property
"__proto__". For example,

Fruit={__proto__:null, apple:true, pear:true, orange:true}

will create an object that I can rely to implementing a fruit type
decider:

Fruit['apple']; // true
Fruit['orange']; //true
Fruit['pecan']; //false
Fruit['toString']; //false

However, in other browsers such as Opera, which don't support
"__proto__" property, Fruit['toString'] will evaluate to a function,
which is converted to true. Therefore, I am wondering how can I avoid
accidentally accessing properties inherited from object in the
prototype chain?

Thanks,
Yan Huang
 
T

Thomas 'PointedEars' Lahn

Yan said:
Firefox's JS engine implementation has a built-in property
"__proto__". For example,

Fruit={__proto__:null, apple:true, pear:true, orange:true}

will create an object that I can rely to implementing a fruit type
decider:

Fruit['apple']; // true
Fruit['orange']; //true
Fruit['pecan']; //false
Fruit['toString']; //false

However, in other browsers such as Opera, which don't support
"__proto__" property, Fruit['toString'] will evaluate to a function,
which is converted to true. Therefore, I am wondering how can I avoid
accidentally accessing properties inherited from object in the
prototype chain?

Are you expecting a serious answer to that?


PointedEars
 
L

Lasse Reichstein Nielsen

Yan Huang said:
Firefox's JS engine implementation has a built-in property
"__proto__". For example,

Fruit={__proto__:null, apple:true, pear:true, orange:true}

will create an object that I can rely to implementing a fruit type
decider:

Fruit['apple']; // true
Fruit['orange']; //true
Fruit['pecan']; //false
Fruit['toString']; //false

However, in other browsers such as Opera, which don't support
"__proto__" property, Fruit['toString'] will evaluate to a function,
which is converted to true. Therefore, I am wondering how can I avoid
accidentally accessing properties inherited from object in the
prototype chain?

You can't avoid looking up a value if you write Fruit['toString'].
That type of lookup always use the prototype chain.

You can, however, check whether the property is inherited using
Fruit.hasOwnProperty('toString').
Or you can overwrite the toString property with the value "unknown",
i.e.: "Fruit.toString = unknown;". I can't recommend that, though.

/L
 
T

Thomas 'PointedEars' Lahn

Lasse said:
[...]
Or you can overwrite the toString property with the value "unknown",
i.e.: "Fruit.toString = unknown;". I can't recommend that, though.

s/unknown/undefined/?


PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
Lasse said:
[...]
Or you can overwrite the toString property with the value "unknown",
i.e.: "Fruit.toString = unknown;". I can't recommend that, though.

s/unknown/undefined/?

Ahem, yes, ofcourse.

/L *blush*
 
T

Thomas 'PointedEars' Lahn

kangax said:
`hasOwnProperty` is generally unreliable too. It:

1) can return false positives:
`({}).hasOwnProperty('__count__') === true` in Gecko

Apparently that is so:

var o = {};
o.__proto__ = null;
console.log(o.__count__);

Comment out the second line and the result is `undefined' instead if `0', so
the object referred to by `o' inherits that property instead. Has a bug
been filed yet?


PointedEars
 
T

Thomas 'PointedEars' Lahn

kangax said:
`hasOwnProperty` is generally unreliable too. It:

1) can return false positives:
`({}).hasOwnProperty('__count__') === true` in Gecko

Apparently that is so:

var o = {};
o.__proto__ = null;
console.log(o.__count__);

Comment out the second line and the result is `0' instead of `undefined', so
the object referred to by `o' inherits that property instead. Has a bug
been filed yet?


PointedEars
 
V

VK

Thomas said:
  var o = {};
  o.__proto__ = null;
  console.log(o.__count__);

Comment out the second line and the result is `0' instead of `undefined',so
the object referred to by `o' inherits that property instead.  Has a bug
been filed yet?

__proto__, __andOtherStuffOfTheKind__ is a hack, more exactly a
debugging tool left from the time when Netscape team was preparing the
new engine. If one is using a hack then nothing is guaranteed and
everything is on one's personal responsibility. Just like if someone
instead of (referring Java):
boolean foobar;
foobar = false;
would try to use some known system vulnerability for direct memory
access and the relevant heap allocation. What results consistency are
expected in this case?

If we started to talk about hacks in application to objects, here is
one from my collection. It is based on the fact that \0 escape
sequence is used as the system level string terminator yet "wisely"
allowed by JavaScript specs to be a part of a string. Not too many
browsers are still able to cope with it. To get fun any version of IE
is needed or Safari or Opera (Gecko and Chrome are fixed it):

<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
</head>
<body>
<script type="text/javascript">
var obj = new Object();
obj['foobar'] = 'foobar\0secret part';
window.alert(obj.foobar); // 'foobar'
window.alert(obj.foobar.substring(7)); //'secret part'
</script>
</body>
</html>
 
J

Jorge

Thomas said:
  var o = {};
  o.__proto__ = null;
  console.log(o.__count__);
Comment out the second line and the result is `0' instead of `undefined', so
the object referred to by `o' inherits that property instead.  Has a bug
been filed yet?

__proto__, __andOtherStuffOfTheKind__ is a hack, more exactly a
debugging tool left from the time when Netscape team was preparing the
new engine. If one is using a hack then nothing is guaranteed and
everything is on one's personal responsibility. Just like if someone
instead of (referring Java):
 boolean foobar;
 foobar = false;
would try to use some known system vulnerability for direct memory
access and the relevant heap allocation. What results consistency are
expected in this case?

If we started to talk about hacks in application to objects, here is
one from my collection. It is based on the fact that \0 escape
sequence is used as the system level string terminator yet "wisely"
allowed by JavaScript specs to be a part of a string. Not too many
browsers are still able to cope with it. To get fun any version of IE
is needed or Safari or Opera (Gecko and Chrome are fixed it):

<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
 content="text/html; charset=iso-8859-1">
</head>
<body>
<script type="text/javascript">
var obj = new Object();
obj['foobar'] = 'foobar\0secret part';
window.alert(obj.foobar); // 'foobar'
window.alert(obj.foobar.substring(7)); //'secret part'
</script>
</body>
</html>

javascript:alert('foobar\0secret part');

Safari 3.23 : 'foobarsecret part'
Safari 4.03 : 'foobarsecret part'
FF 2.0.0.20 : 'foobar'
FF >= 3.0.13 : 'foobarsecret part'
Opera 9.64 : 'foobar'
Opera 10.00 : 'foobar'
Chrome 4.0.221.8: 'foobarsecret part'
 
T

Thomas 'PointedEars' Lahn

kangax said:
What exactly is a bug here? `__count__` returns exactly what it's
supposed to return — number of "own" properties of an object.

A rather curious question, coming from you who presented the example.
Apparently `__count__' is an inherited property, yet it is recognized
as a non-inherited one.


PointedEars
 
V

VK

Jorge said:
javascript:alert('foobar\0secret part');

Safari 3.23     : 'foobarsecret part'
Safari 4.03     : 'foobarsecret part'
FF 2.0.0.20     : 'foobar'
FF >= 3.0.13    : 'foobarsecret part'
Opera 9.64      : 'foobar'
Opera 10.00     : 'foobar'
Chrome 4.0.221.8: 'foobarsecret part'

It is as funny as a value of an object property. And if one start
experimenting with "hacked" property names instead of values and then
with hacked property values assigned to hacked property names then the
day just goes by. Actually if many browsers would not fix it by now
then it could be a very specific encapsulation system build on it :)
Alas for me it is an old toy but I wish all fun to however just got
it.

In the continuation of JavaScript strings hacking here is another item
from my collection based on the mutually exceptive rules for the
internal JavaScript tokenizer (each line ends by \ with nothing after
it). Here absolutely any browser will fit:

<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
</head>
<body>
<script type="text/javascript">
var foobar = 'Lorem ipsum dolor sit amet,\
consectetur adipisicing elit,\
sed do eiusmod tempor incididunt\
ut labore et dolore magna aliqua.\
\n\t\
Use Lorem Ipsum generator\
at http://www.lipsum.com !';

window.alert(foobar);
</script>
</body>
</html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top