I'm TRWTF (javascript eval)


  • SockDev

    i'm about to put this into production...

    var request = require('request'),
        xRegExp = require('xregexp').XRegExp,
        vm = require('vm'),
        languages;
    request.get('http://ackuna.com/cjs/badtranslator.js', function (err, resp, body) {
        var r = xRegExp('languages[.]push\\(\\{[^}]+\\}\\)'),
            i = 0,
            res = "var languages=[];",
            match = 1,
            ctx = {};
        while (match) {
            match = r.xexec(body, i);
            if (!match) {
                continue;
            }
            i = match.index + match[0].length - 1;
            res += match[0] + ';';
        }
        vm.runInNewContext(res, ctx, 'badtranslator.js');
        languages = ctx.languages)
    });
    

    That's right i'm using javascript's eval (albeit a slightly safer variation than straight eval, that's what vm.runInNewContext does.)

    i am TRWTF.


    filed under:

    $('body').css('font-family', 'monospace');
    


  • I don't seriously javascript (as in, the do-it-with-jquery answers appear really intelligent). How is eval() being used here. Is that in "vm", whatever that is?


  • SockDev

    yes. vm.runInNewContext is pretty much straight eval with some basic sanity checking and sandboxing put in place. it's nowhere near perfect but it's good enough that between it and my sanitizing regexp (because i'm only interested in the final languages array) i've got decent security in place.

    it's still a WTF to put into production.



  • Am I missing something? All you seem to be doing is stuffing languages array with language objects from this file.

    languages.push({name:"Korean",Babelfish:"ko",Bing:"ko",SDL:null,TransPerfect:null,Yandex:null})
    

    ?


  • SockDev

    via eval, yes.



  • ....why? You intentionally trying to be TRWTF?



  • Serious question, do you need help to get rid of the vm, or you're intentionally doing it this way?


  • Winner of the 2016 Presidential Election

    It's for a TDWTF bot so I think it's an intentional wtf.



  • @royal_poet said:

    It's for a TDWTF bot so I think it's an intentional wtf.

    Yeah, that's what I wanted to know. Didn't want to start preaching with the "correct" solution if the goal was to be WTF. So, half-whoosh?


  • Winner of the 2016 Presidential Election

    If you fancy teaching me I'd love to learn how you go about it more intelligently. XD I think for me it would have been a WTF for not knowing any better.



  • This works with the current makeup of the target file. Of course, if the file structure is subject to change, the vm solution would probably be more durable.

    var request = require('request');
    
    function getLanguages(callback) {
    	request.get('http://ackuna.com/cjs/badtranslator.js', function (err, resp, body) {
    		if (err) {
    			return callback(err);
    		}
    
    		var lanRegExp = /languages\.push\((\{[^}]+\})\)/g,
    			kvRegExp = /([^{,:]+)\:([^,}]+)/g,
    			match,
    			jsonFriendlyKv,
    			buffer = [];
    		while (match = lanRegExp.exec(body)) {
    			jsonFriendlyKv = match[1].replace(kvRegExp, "\"$1\":$2");
    			buffer.push(jsonFriendlyKv);
    		}
    
    		var languages = JSON.parse("[" + buffer.join(",") + "]");
    
    		return callback(null, languages);
    	});
    }
    

  • Winner of the 2016 Presidential Election

    Oh, that does look neater. Thank you. I really don't know my Javascript half as well as I should. I did a module on it in uni but never used it in production.

    It's rather pathetic how much good practise I've forgotten.


  • SockDev

    i decided i didn't like eval.

    so i rewrote it last night to be this (nodeJS containing function and callback elided for brevity)

    var request = require('request'),
        xRegExp = require('xregexp').XRegExp;
    
    request.get('http://ackuna.com/cjs/badtranslator.js', function (err, resp, body) {
        var r = xRegExp('languages[.]push\\((\\{[^}]+\\})\\)'),
            i = 0,
            languages = [],
            match = 1;
        while (match) {
            match = r.xexec(body, i);
            if (!match) {
                continue;
            }
            i = match.index + match[0].length - 1;
            try {
                languages.push(JSON.parse(match[1].replace(/({|,)([^:]+)/g, '$1"$2"')));
            } catch (e) {
    
            }
        }
    });
    

    I'll have to give yours a go too, i'd love to be able to drop the dependency on xregexp



  • How annoying is that stupid json can't swallow unquoted keys? That's the only reason you'd even contemplate using vm/eval. They should just add that feature and call it json 1.1. And comments too.


  • SockDev

    we would appreciate it...


  • SockDev

    that works and removes the dependency.

    as usual containing function and callback structure elided for brevity.

    var request = require('request');
    
    request.get('http://ackuna.com/cjs/badtranslator.js', function (err, resp, body) {
        var lanRegExp = /languages\.push\((\{[^}]+\})\)/g,
            kvRegExp = /([^{,:]+)\:([^,}]+)/g,
            match = 1,
            languages = [];
        while (match) {
            match = lanRegExp.exec(body);
            if (!match) {
                break;
            }
            languages.push(JSON.parse(match[1].replace(kvRegExp, "\"$1\":$2")));
        }
    });
    

    (changed up slightly to pass jslint with opts:

    /*jslint node: true, indent: 4 */
    

    )



  • Ah, so the strange while construct is to make lint happy. Didn't figure that out.


  • SockDev

    yeah, i could tell jslint to allow assignment in conditionals, but i can't be bothered to and it has caught bugs in my code before.

    i may not agree with crockford on all his rules of JS but i do agree that assignment in conditionals (and the while is a conditional) is dangerous as it can hide bugs and cause behavior one does not expect.

    although i just tested this:

    /*jslint node: true, indent: 4 */
    (function () {
        'use strict';
        var request = require('request');
    
        request.get('http://ackuna.com/cjs/badtranslator.js', function (err, resp, body) {
            var lanRegExp = /languages\.push\((\{[^}]+\})\)/g,
                kvRegExp = /([^{,:]+)\:([^,}]+)/g,
                match = 1,
                languages = [];
            while ((match = lanRegExp.exec(body))) {
                languages.push(JSON.parse(match[1].replace(kvRegExp, "\"$1\":$2")));
            }
        });
    }());
    

    and JSLint accepts it. that cuts 4 lines so i'll take it!



  • Nice! I like the construct with double corners. It's the best of both worlds - both concise and clear there's something special going on.


  • SockDev

    indeed. i think that's why JSLint accepts it.



  • @cartman82 said:

    I like the construct with double corners.

    What does "double corners" mean in this context?


  • Winner of the 2016 Presidential Election

    I was wondering this too. /royal poet snow knows nothing.



  • My js experience is very limited. I'm currently working with a charting package, so I'm learning some interesting things / techniques.


  • Winner of the 2016 Presidential Election

    Same here.

    <- Fortran girl.



  • @royal_poet said:

    <- Fortran girl.

    So you can tell @Arantor that he's no longer TRWTF. FORTRAN > PHP.

    I haven't touched any FORTRAN in years. It was a vapor / droplet dispersion simulation. I don't recall which version of FORTRAN it was written in (this was probably 12 years ago) but I know that it came with a set of WTF batch scripts as a build "system." And of course, I had to use a more recent version of FORTRAN, so there was a lot of touch ups I needed to do to get it to build.



  • @boomzilla said:

    What does "double corners" mean in this context?

    Nothing. They are stripped by the interpreter.

    It's just saying to the linter that you're aware you're doing assignment inside an if statement and not to bother warning you about it.

    I've heard this used in C too.



  • @cartman82 said:

    Nothing. They are stripped by the interpreter.

    Were you referring to the comment with the hint or whatever?


  • Winner of the 2016 Presidential Election

    I'm in oil and gas so lots of legacy crap to support that was commissioned 35+ years ago and is still running.

    On the newer jobs I don't even get to touch the code. It's all written by some dudes from kerbleckistan. This is when senior software engineer becomes a euphemism for XML editor.


  • SockDev

    @boomzilla said:

    What does "double corners" mean in this context?

    they're that second set of parens in that while statement.

    in JS you can use parens in all sorts of places that you wouldn't expect them to have meaning. basically what they're doing here is changing a statement (assign a value to match) with an expression that evaluates to the result of a statement.

    it doesn't change behavior at all compared to not having the extra parens there (js would have done the same thing it's doing now) but by making it explicit JSLint regognizes that the assignment was intended and no longer complains about it.


  • SockDev

    specifically the rule we're talking about is from this page: http://www.jslint.com/lint.html

    (i'd have linked directly to that section but there are no a name= tags on that page... sadness)



  • @accalia said:

    they're that second set of parens in that while statement.

    Ahhhhh. Thank you.


  • SockDev

    no problem. i hate to see confusion linger when i can resolve it.



  • Thank you. Bad explanation day.


  • Discourse touched me in a no-no place

    @boomzilla said:

    So you can tell @Arantor that he's no longer TRWTF. FORTRAN > PHP.

    It could be worse: it could be IDL. (Never encountered it? Think proprietary scripted Fortran with weird-ass array slicing operators. HATEHATEHATE.)


  • Winner of the 2016 Presidential Election

    Try PLC programming on stuff thats been deployed since the 1990s. Lots of proprietary crud that screws up even the simplest things, and never conforms to IEC 61131-3.


  • Discourse touched me in a no-no place

    The worst part of dealing with IDL is that virtually everyone who really knows anything about programming does their best to avoid it, which means that the users who are there produce the most awful code imaginable.

    I've seen it seriously proposed that a file containing a whole load of snippets that were just cut-n-paste into the IDL console was a genuine program, ready for production roll-out to the whole field. Persuading the senior scientist involved that it would need some work to make it usable by his colleagues (or anyone else) was a terrible job. Nice guy, but we had to be so rude about what he'd done (and then be very polite to discover all the bits that were still in his head and that he'd never written down at all). Frustrating.


  • Winner of the 2016 Presidential Election

    One of those clients - painful.



  • @boomzilla said:

    I haven't touched any FORTRAN in years. It was a vapor / droplet dispersion simulation.

    FORTRAN was the first language I ever studied in school. The last time I touched it was in a numerical methods, or some such, class. The only things I remember about the class are that it was taught by a guy from the Aero Eng department, and we got to go out to the Aero building and fly their A-10 (I think it was) simulator. (That was a [female dog] to fly; there is so much mass out on the wings that it is really hard to start a roll, and once you get it started, it's hard to stop. The simulator had very limited capabilities: no motion or projection, only instruments, and they had a limited range — roll too far, and you had no clue whether you were in a steep bank or completely upside-down. Let's just say my flight was not successful.)


  • area_deu

    Could you at least shoot a virtual GAU-8?
    @Steve_The_Cynic



  • Sadly, no.


  • Discourse touched me in a no-no place

    @HardwareGeek said:

    The simulator had very limited capabilities: no motion or projection, only instruments, and they had a limited range — roll too far, and you had no clue whether you were in a steep bank or completely upside-down.

    I believe that sort of thing is a problem when flying on instruments only in a real aircraft too. Confusion about what the instruments were saying during times when there were no visual cues (e.g., night, thick cloud, storms, fog) has been the cause of a lot of loss of life, alas…

    Filed under: a sad statistic with too many examples for it to be fair to list them here…



  • @dkf said:

    Confusion about what the instruments were saying during times when there were no visual cues

    I've always understood that the bigger problem was the pilot relying on his senses instead of his instruments.



  • @boomzilla said:

    I've always understood that the bigger problem was the pilot relying on his senses instead of his instruments.

    The confusion comes from the pilot's all-too-human instinct to trust his or her spatial senses, even to a limited degree, over what the instruments say...

    Filed under: hrm...maybe I should build a GA-sized version of the SR-71's PVD...


  • Discourse touched me in a no-no place

    @boomzilla said:

    I've always understood that the bigger problem was the pilot relying on his senses instead of his instruments.

    In some cases, and in others it is (some of) the instruments that are telling lies, perhaps because they've iced up. In any case, it certainly seems that instrument-only flight is harder.

    My local airport has low-flying cloud fog so often that commercial pilots are only allowed to fly into it if they're fully qualified for instrument-only flight. It doesn't help that the runway isn't level either…



  • @dkf said:

    In some cases, and in others it is (some of) the instruments that are telling lies

    In the case of that simulator, both your senses and the instruments were lying, which left you pretty much SOL.



  • @dkf said:

    My local airport has [s]low-flying cloud fog[/s] so often that commercial pilots are only allowed to fly into it if they're fully qualified for instrument-only flight. It doesn't help that the runway isn't level either…

    I haven't been able to find anything in the AIP text that says that VFR into EGCC isn't allowed...


  • Discourse touched me in a no-no place

    @tarunik said:

    I haven't been able to find anything in the AIP text that says that VFR into EGCC isn't allowed...

    You're buttuming that that is my local airport…



  • @dkf said:

    You're buttuming that that is my local airport…

    Well, your profile location does say Manchester, UK...


  • Discourse touched me in a no-no place

    So? That's where I work…


  • Discourse touched me in a no-no place

    @boomzilla said:

    I haven't touched any FORTRAN in years.

    I learned FORTRAN in 1988 in college, managed to get through the class with a passing grade, but also managed to forget everything I'd learned before the end of the class, somehow.

    I actually used COBOL professionally once, in about 1996.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.