Cenzic 232 Patent
Paid Advertising
sla.ckers.org is
ha.ckers sla.cking
Sla.ckers.org
Q and A for any cross site scripting information. Feel free to ask away. 
Go to Topic: PreviousNext
Go to: Forum ListMessage ListNew TopicSearchLog In
Pages: Previous1234567891011...LastNext
Current Page: 3 of 13
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 24, 2009 10:22AM

I also just noticed that `in` operator, while syntactically supported, is somewhat useless now, since property name doesn't seem to be coerced before it's being used in `in` :)

var o = { x: 1 };
'x' in o; // false

Maybe some kind of a wrapper would help:

`'foo' in obj;` ==> `in_operator(obj, 'foo');` => `'$foo$' in obj;`

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 24, 2009 10:40AM

eval('eval(1)');
Was expecting `1`, got `TypeError`.

eval('with(window){ alert(typeof eval) }');
Was expecting "function", got "undefined"

This - ['x'],['x'] - for some reason, is being parsed inconsistently -

Array(String('x')), [globals.gp(String('x'))]

Which results in weirdness like -

(['x'], ['x'])[0] === 'x'; // `false`, should be `true`

P.S. It also looks like strings don't have a `length` property, do they?

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 24, 2009 11:18AM

Quote

How come `undefined` is being coerced to pseudo-window object (when invoking function with call/apply) and `null` isn't?

Yeah that's a bug. I return null because $window$ isn't available in the scope of the function but I can fix this.

Quote

var o = { x: 1 };
'x' in o; // false

Great find! Yeah I need to replace strings when used with a in operator

Quote

P.S. It also looks like strings don't have a `length` property, do they?

I did have length whitelisted but now I think I can add it in the prototypes.

Thanks kangax! I'll fix the others too

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: rvdh
Date: July 25, 2009 01:19AM

According to Oshuma from this day forth, null shall be called lul.

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Anonymous User
Date: July 25, 2009 05:17AM

eval('ale'+[]+'rt'+'(1)') //ReferenceError: $ale$undefined$rt$ is not defined

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 26, 2009 03:38PM

Quote

How come `undefined` is being coerced to pseudo-window object (when invoking function with call/apply) and `null` isn't?

This is now fixed, it returns the $window$ instead of null ;)

Quote

var o = { x: 1 };
'x' in o; // false

I rewrite the "in" operator when it's not being used inside a for(i in ) loop. JSReg now has a special globals.inOperator which replaces your property with $prop$

Quote

eval('eval(1)');
Was expecting `1`, got `TypeError`.

This was a bug in the symbols, it was making the eval function undefined when used twice.

Quote

eval('with(window){ alert(typeof eval) }');
Was expecting "function", got "undefined"

Fixed related to the previous one

Quote

This - ['x'],['x'] - for some reason, is being parsed inconsistently -

Yep Arrays are a headache for me as I need to make sure I only match arrays and not obj['string']. Adding the , to the lookahead solved this problem.

Quote

eval('ale'+[]+'rt'+'(1)') //ReferenceError: $ale$undefined$rt$ is not defined

Fixed! The arrays weren't being matched inside the eval when using them as strings :)

Thanks all again!

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Anonymous User
Date: July 26, 2009 04:36PM

Awesome stuff Gareth! I am currently thinking of connecting our JS framework with JSReg.

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 27, 2009 11:15AM

`in` doesn't work "everywhere" yet:

'x' in { x: 1 }; // `false`, should be `true`

Also, don't forget that whitespace (as a separator between operator and operand) can often be omitted, if overall expression/statement makes sense.

'x'in{x:1}; // SyntaxError, should be `true`

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 27, 2009 02:37PM

`in` doesn't seem to work in loop either:

for (var p in { x: 1 }) { }; // ParseError

Also, some other operators "fail" to be parsed properly with omitted whitespaces:

''instanceof String; // SyntaxError

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 27, 2009 02:54PM

@kangax

Yep the in operator is a bit rough yet :)
I'm working on it, should have a fix soon thanks!

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 28, 2009 02:55AM

@kangax

In operator fixed now :)

this is allowed:-
for (var p in { x: 1 }) { };

and this:-
'x'in{x:1};

Thanks!

Other updates include:-
-Works in FF2, <FF3.5 by fixing object constructor bug
-Couple of tweaks found with JSLint
-Debug objects now allow you to switch off the eval calls:-
doNotMainEval: false,
doNotEval: false,
doNotFunctionEval: false
-Fixed problem with eval not remembering which symbols extracted e.g.:-
x=123;
eval("x")
-Fixed scoping problem with eval which allowed global variables $$:-
eval("x=123") // window.$x$

Update...
This took a bit of working out but now this is possible :D
(((('x'))))in{x:1}

Yes my RegExp fu is strong now ha-ya

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]



Edited 1 time(s). Last edit at 07/28/2009 05:09AM by Gareth Heyes.

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 28, 2009 09:49AM

Almost there, but not quite:

var x = 5; x--in{'5':1}; // SyntaxError

for (var p in o = { x: 1 }) { alert(p) } // No alert

for (var p in /x/) { alert(p) }; // ParseError
for (p in 'x') { alert(p) }; // ParseError

Also, for/in now enumerates over originally non-enumerable "constructor", "prototype", "valueOf" and "toString" (and, I think, also through "call"/"apply" on Function objects). From what I can see, this is due to same-named (but surrounded with "$") properties added to `Object.prototype`.

There's also no `hasOwnProperty` to filter those out ; )

I think it would be much more effective to find all these deviations through something like "sputniktests" http://code.google.com/p/sputniktests/ (although it wouldn't be much fun anymore :)). It's a set of over 5000 ES3 conformance tests recently released by Google. If you clearly define a subset of ES3 that your parser is emulating - such as, no global object coercion of `this`, or other potentially dangerous quirks - it should be easy to just strike some tests out and focus on passing the rest of them.

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 28, 2009 09:57AM

Couldn't resist...

6-1in{'5':1}; // expected: `true`, actual: `6`
/a/ in { '/a/' : 1 }; // expected: `true`, actual: `false`
void 0 in { 'undefined' : 1 }; // expected: `true`, actual: `undefined`

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 28, 2009 10:10AM

@kangax

Haha crazy syntax :D

Thanks for the sputniktests, I might try that :) Then it should be very difficult to find parsing errors :D

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 06:33AM

@kangax

The "in" operator should be fixed now...man this was tough. I had all sorts of performance problems when I implemented it the first time. My main problem is that js doesn't support lookbehind at all natively grrrrr. I was almost tempted to write the parser in php.

I'm working on a js testing section so I should be able to automate some tests using sputniktests in future.

I know I keep saying it but thanks again! You are really helping JSReg development

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 29, 2009 07:42AM

No problem. Here's another batch for you : )

'x' in/x/; // expected: false, actual: SyntaxError
'x'in((((({x:1}))))) // expected: true, actual: SyntaxError
'x','y'in{'y':1}; // expected: true, actual: SyntaxError

Speaking of comma operator (as in the last example), is it even supported? I see another case where it fails:

[1,2,3][1,2]; // expected: 3, actual: 2

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 08:45AM

@kangax

Quote

Speaking of comma operator (as in the last example), is it even supported? I see another case where it fails:

Yeah this was a bug. I force the comma operator now by surrounding with () :)

To help understand the issue here is what JSReg does to this code:-
[1,2,3][1,2];

Becomes:-
//removed some lines for clarification 
[1,2,3][globals.gp((1,2))]
globals.gp=function(exp){
     return '$' + exp + '$';
}

All others fixed thanks!

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 29, 2009 09:47AM

That one seems to work now, but something like this still fails:

[[[1,2,3][1,2]][0]]; // expected: [3], actual: SyntaxError

Also, is it something on my side or is for-in broken again?

for (var p in {}) p; // ParseError

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 10:35AM

@kangax

Quote

Also, is it something on my side or is for-in broken again?
for (var p in {}) p; // ParseError

I didn't account for the {} in the separate for..in loop, previously it only checked after an assignment. Probably needs some more work actually. Fixed it for now.

Quote

[[[1,2,3][1,2]][0]];

Yeah this is tricky if you remove the last enclosing [] it works, the problem is my regexps look for certain characters after but can't check before because of the lookbehind limitation. I'll try and fix this or maybe I'll fix it in the php version where I can have lookbehind!

Cheers

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 11:26AM

@kangax

Ok both fixed now whoo hoo. I've added those to the JS tests as they are tricky

Thanks!

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 29, 2009 01:00PM

for(var p in((/x/))) p; // ParseError
for (p in[1,2,o=/x/]) p; // ParseError
for(p in-1) p; // ParseError
for((p)in({})) p; // ParseError

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 02:20PM

@kangax

Thanks and fixed!

I've also added a separate regpexp for instanceof

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 29, 2009 02:49PM

Allrighty :)

({ x: 1 }).hasOwnProperty('x'); // false, should be true
({}).hasOwnProperty('toString'); // true, should be false

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 29, 2009 03:45PM

@kangax

Yeah I'm a dumbass :) ! fixes it

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 29, 2009 09:23PM

Is it already fixed?

({}).hasOwnProperty('x'); // still gives `true`

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 30, 2009 02:51AM

Sorry it should work now thanks!

Update...
After horrible performance problems with the in/instanceof operator, I decided to take a different approach :)

inInstanceofOperator = new RegExp().compile("\\s*in(?:stanceof)?(?=[\\/\\d\"'\\[\\s\\(\\{])"),

I then hack the object without knowing what it is. So for example (1)in{1:123} becomes :- (Number(1)).inOperator()in {1:Number(123)} this is all because javascript doesn't support lookbehinds! So I know it's a hack but you know what else could I do imagine trying to match stuff like:-

(123,123),(123,'xyz') in {}

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]



Edited 1 time(s). Last edit at 07/30/2009 09:24AM by Gareth Heyes.

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 30, 2009 09:23AM

({ toString: 1 }).hasOwnProperty('toString');

expected: true, actual: false

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 30, 2009 09:31AM

@kangax

Fixed I hope. Just calls the hasOwnProperty now with a wrapper for $$ and because I use prototype for the other methods it should return the correct values thanks!

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: kangax
Date: July 30, 2009 11:02AM

Yep, seems fixed now. But here's something else:

for (var p in function(){}) p; // SyntaxError

and `inOperator` is still being iterated over in for-in

Options: ReplyQuote
Re: JSReg sandbox challenge
Posted by: Gareth Heyes
Date: July 30, 2009 11:52AM

@kangax

Good one! Fixed! My regexp was doing .+ instead of .*? which failed to match () inside ( )

inOperator can be removed using hasOwnProperty, I know it sucks but there's no other way unless I add code to remove it inside the for..in loop.

Also I'm struggling with prototypes, I wanted to remove the prototypes after the eval has finished. Any ideas how to do this without creating a new window context?

My problem is this:-
var Number = function(v) { this.x=function() { alert(1); }; this.valueOf=function() { return v } };
Number.prototype=window.Number;
(new Number(1)+new Number(1)).x()// is not called :(

also: typeof new Number(1) === 'object' // :(

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]



Edited 1 time(s). Last edit at 07/30/2009 11:57AM by Gareth Heyes.

Options: ReplyQuote
Pages: Previous1234567891011...LastNext
Current Page: 3 of 13


Sorry, only registered users may post in this forum.