Tip: Relaxing JSON strictness

I’ve decided to start posting about the little things I encounter day by day. Post #1: I needed less strict JSON parsing than Firefox usually does and a little RegEx seems to do the trick for now (it also allows for single word strings à la PHP, e.g. FOO becomes “FOO”:

var findRelevantToken=/(?:"(?:|.*?[^\\](?:\\\\)*)"|([\s,\:\{\[]|^)([a-z\_\$][a-z\_\$0-9]*))/gi;
   str=str.replace(findRelevantToken,function(m,ssep,nqs){
   if(nqs) return ssep+'"'+nqs+'"';
   else return m;
});

References vs. Pointers in Javascript

I’m as guilty as the next guy when it comes to the confusion surrounding the terminology used for variables that get assigned objects, but I think it’s time to get my act together and define a standard at least for myself:

If “new Object()” is an OBJECT, then “var obj=new Object()” makes obj a POINTER. Why is that?

The important thing here is considering what it is not. It is definitely not the actual OBJECT, because if that variable were the actual OBJECT (even if only at that particular moment), then “var obj2=obj” would have to make obj2 its own OBJECT too. But it doesn’t: Instead it points to the same OBJECT as obj does.

So that means that obj can only be a POINTER or a REFERENCE, since it doesn’t actually contain the OBJECT like it does for strings or numbers.

It’s tempting to call it a REFERENCE and I wouldn’t object to it if it weren’t for the fact that Javascript actually has real references, meaning variables that if set will cause another variable to change its value. This happens every time you access the arguments of a function:

(function(myArg){
    alert(myArg+" "+arguments[0]);
    arguments[0]="SET-BY-REF";
    alert(myArg+" "+arguments[0]);
    myArg="SET-BY-VARIABLE";
    alert(myArg+" "+arguments[0]);
})("INITIAL");

Which will print out “INITIAL INITIAL”, “SET-BY-REF SET-BY-REF”, “SET-BY-VARIABLE SET-BY-VARIABLE” in that order.

To be honest, this isn’t really something that you’ll encounter very often and it rarely is of much use, but it definitely makes myArg a REFERENCE of arguments[0], (meaning that any change to variable 1 will be reflected on variable2 – almost. In this case a change to a property will be reflected on a variable and vice-versa, but it’s so very close that it’s difficult to imagine that you’d use the term for variables pointing to an object, but not for this).

So, if obj can’t rightly be called a REFERENCE or an OBJECT, it has to be something else. And pointer seems to fit the bill very nicely, so that’s what I’m going to call it. Let’s see if it catches on 😉

Adding icons to bookmarklets … again

Show simple Demo

Yesterday I got a question on how to make my Bookmarklet-with-icon code work and sadly, it seems to be broken now. So I set out to find another method and strangely enough the solution that works with modern Firefox versions is quite simple and elegant:

Open the bookmarklet in "page mode" once after the user has added it as bookmarklet. This may sound like something that’s terribly hard to detect, but with a few simple tricks it’s not much of an issue: Mainly because you can make it so that the user barely notices if it fires to often.

  1. Just like the original bookmarklet-with-icon code, adding icons still relies on the behavior that a javascript: url which returns a string will cause the browser to display that string as a HTML document. So, the first step (again) is saving the HTML string somewhere. Of course, you can still add a bit of randomness, but for simplicity’s sake we’ll leave it out for now:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
          +'</head>'
          +'<body></body>'
        +'</html>'
      ;
    </script>

  2. Now, we add the magic favicon sauce:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
            +'<link rel="icon" href="http://www.my.domain/favicon.ico" />'
          +'</head>'
          +'<body></body>'
        +'</html>'
      ;
    </script>

  3. Like I said, we want that page to only appear very briefly, so we add a history.back(); call that will take us right back to the previous page. I’ve added a timeout as well, which is probably not necessary, but with hacks like that it’s better to err on the side of caution. It’s also a good idea to split the closing script tag to prevent any browser from misinterpreting it as the end of the current script block:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
            +'<link rel="icon" href="http://www.my.domain/favicon.ico" />'
          +'</head>'
          +'<body>'
            +'<script>'
              +'window.onload=function(){'
                +'window.setTimeout(function(){'
                  +'history.back();'
                +'},250);'
              +'};'
            +'</scr'+'ipt>'
          +'</body>'
        +'</html>'
      ;
    </script>

  4. And that’s pretty much it for our magic assign-icon-from-within-bookmarklet page. Now we just have to change the actual bookmarklet to return that HTML string instead of running the bookmarklet code whenever a thusly-named HTML string exists on the current page. Assuming our bookmarlet is a plain old alert("This is my bookmarklet");void(0);, we have to wrap it into a little if-block like this:
    if(top["bookmarkletv2sample@tapper-ware.net"]){
       top["bookmarkletv2sample@tapper-ware.net"];
    }else{	
       alert('This is my bookmarklet');
      void(0);
    }


    which, written as a bookmarklet one-liner, turns into

    <a href="javascript:if(top['bookmarkletv2sample@tapper-ware.net']){top['bookmarkletv2sample@tapper-ware.net'];}else{alert('This%20is%20my%20bookmarklet');void(0);}">My Bookmarklet</a>

  5. If you put those blocks somewhere on your page it will already work… sort of: If you drag the link to your bookmarks-toolbar, then click it, you’ll briefly see an empty page and the icon will appear. Now, all we have to automate is that one click. Luckily, all we have to do for that is listen for a dragend event, which occurs whenever the user drags the link anywhere. It also occurs during any other drag operation but since that brief refresh is barely noticeable it doesn’t really matter if we try to assign the icon too often. All we have to do for that is add an ondragend attribute to the a element:
    ondragend="this.click();"


    Which finally turns our “A” element into this:

    <a ondragend="this.click();" href="javascript:if(top['bookmarkletv2sample@tapper-ware.net']){top['bookmarkletv2sample@tapper-ware.net'];}else{alert('This%20is%20my%20bookmarklet');void(0);}">My Bookmarklet</a>

And that’s all there is to it. Include the link and the script element on your page, tell the users that they should add it by dragging the link and that it won’t work on the current page, adjust favicon-url and exchange the example with your own JS code. Done.

Listening in on WebGL : WebGLProfiler

I’ve been trying to learn a thing or two about WebGL, but I’ve encountered a very simple problem: Most examples you find on the web have a very complex source code that is great for demonstrating how the particular framework the developer has written/used works, but usually not so great for learning WebGL itself.

For example take a look at this sample that often turns up when you ask about realtime shadows. It’s a beautiful little thing, but it uses Google’s O3D framework, so if you want to learn about the GL code involved, without learning about O3D, you’re pretty much out of luck.

So I decided to hack up something that can give me a runnable version of all the GL calls involved in this, complete with symbolic constants at least for the most common GL calls (have a look at the top of the source to see what arguments are currently resolved). It’s very hackish and may not always work perfectly (for example, it replaces all intervals and timeout with a value of 10000 so that you don’t get flooded with frame updates, meaning that it could take a while for what you’re interested in to appear), but it creates a WebGL program that’s strictly linear and pretty easy to read. Since it was built for my own use it also has some pretty ugly hacks that could be solved more elegantly with enough time (for example it checks for the document’s load state using an interval waiting for the title tag to appear), but it works. The resulting HTML page will have snapshots of canvases or videos embedded, while the images are links to the originals.

The big drawback so far is that you’ll only get the raw values of matrices, since these are not handled by WebGL, but by a few different libraries. It’s a big drawback, since it means that you will have to look them up in the original source code, but if they are probably named (global variable names are inserted by the profiler as comments and if there is none, you can always look at the names used inside the shaders), you can usually guess them pretty well.

I’ve wrapped the whole thing into a bookmarklet for easy use. When invoked, it will load the current document into the right frame, monkeypatch it and on first use of the webgl context start reporting to the left frame. The left frame will then contain a complete HTML document that you can just copy/paste and it will produce the same output as the original page. Be warned, it will VERY likely only work in current Firefox nightlies.

Perhaps the best way to illustrate it is showing the output of a few samples (look at the source):

You can find the bookmarklet at http://www.tapper-ware.net/data/devel/web/apps/JS.WebGLProfiler/.

License is GPL3 (or later). See the sourcefor details.

Teaching IE8 a bit of Canvas with DataURIs: ducie8.js

Demo Link (ducie8.js uses a native Canvas implementation if found, so you can only really test it in IE8)

I’m still looking for ways to apply this to previous IE versions (which is pretty hard considering that there are no DataURIs, just a bunch of bugs which influence each other is such ways that they might be able to provide similar functionality), but even only with IE8 compatibility this could prove valuable, seeing as IE8 is the highest version that you can ask IE users to update to without a change of operating system or browser.

I was exploring DataURIs in IE a while back with Joseph Huckaby when he published his article on palette animation, since altering the palette in a BMP data url is faster than doing it manually for every pixel through JS and works in IE8 as well. We gave up when we realized that WebKit would simply leak all memory associated with our DataURIs and never release it (2GB can pile up quite quickly if you use about 20MB per second). I still have the source around if anybody is interested, but I’m afraid I don’t have any public domain images to put together a demo.

Anyway, this didn’t really lead anywhere, but it gave me the idea to try emulating Canvas with BMP DataURIs. Now, DataURIs in IE8 are severely limited. Most notably they can’t go beyond 32kb (in fact, no URL can in IE8). The solution is pretty obvious: Use multiple small ones (we already had to do that for the palette animation). Other than that you need a base64 encoder since IE8 doesn’t have an btoa() function and that’s pretty much it.

Of course, when it comes to actually implementing something like that things are never simple and there are a few obstacles that ducie8.js will very likely never overcome. Like the facts that trying to emulate a 32bit Canvas with transparency would require using PNG DataURIs, which in turn would mean that we can’t recalculate the base64 value for an individual pixel (since base64 strings can only be split every 24bits) and would have to recalculate the checksum for the PNG on every change (maybe there are some bugs that allow us to get away with a corrupt checksum, we’ll see). Or that drawImage won’t be able to access normal HTML Image elements (since we can’t access their pixel data), but will require a special Image-like element which will internally use XMLHttpRequest and responseBody (and will only be able to read uncompressed formats unless somebody manages to do an incredibly fast PNG decoder in IE8). Or that we never know when the JS has finished drawing a single frame (which is why ducie8.js right now uses a timeout and updates the BMPs with 1 frame delay). Or that it will never be fast enough for anything but Minesweeper (it’s still surprisingly fast considering that the code is still pretty unoptimized). Or that you have to use the setProp method for setting properties since we often need to run a setter (ducie8.js adds setProp to a real Canvas implementation if found, so that you can at least use the same code for both).

What it can do is provide Canvas in cases where using the server is simply not possible or very undesirable, but the result is mostly static once rendered. Graphs. Buttons. The current version of ducie8.js is very light on features. width, height, fillStyle and fillRect. That’s it. enough for a simple drawing program to test the speed and the architecture, but little else. However the vast majority of Canvas features could be implemented in a pretty straight-forward way and I’ll be happy to set up a project if there’s any interest.

P.S. I should probably stress that the current version uses a triple-cache (nummeric pixel data > base64 pixel data > data url) that’s actually very slow for solid rectangles and really meant for per-pixel access with transparency. So don’t think the current speed is the limit: Internally these are all Arrays and can be made a lot faster by using Array methods instead.

Benchmarking and code optimization in the browser: Emulators

Update: IE9pp4 gets 9710ms , still slowest

The GameBoy emulator posted over at CodeBase is very impressive. Unfortunately, it’s borderline unusable on anything but Chrome. I know Chrome’s V8 engine is always reported to be the fastest JS Engine, but the difference is ridiculous.

Fast Javascript means pleasing the Tracing algorithm built into browsers. If that algorithm can’t understand what you’re trying to do it will fall back to the interpreter and you don’t want to do that (even with Nitro and Jägermonkey). So it was pretty obvious that the problem was just that: Firefox simply didn’t understand the code.

I dove into the JSGB source and found one problem straight away… a problem that is handled remarkably well by Chrome, but even there it makes things about 15% slower. An emulator is basically a big switch statement: If opcode==a then do A, else if opcode==b then do B. In Javascript, you may be tempted to do something like this:

var table={
  a:function(){A;},   
  b:function(){B;},
}
table[opcode]();

That’s exactly what JSGB does. It’s all fine and dandy if you have few calls, but you have to remember that running a function means much more than just running the code: A new context has to be created, the name lookup chain altered, a new analysis profile for tracing created, arguments passed. An emulator does this constantly, so it’s wasting tons of cycles when all you really need is a switch statement:

switch(opcode){
  case a:A;break;
  case b:B;break;
}

The next problem are closures. Going up through the name lookup chain takes its toll, but besides that closures make interpreting Javascript code more complex, making it more likely for the Tracing algorithm to bail out. Apparently on Firefox that’s what’s happening here. An example:

var value=0;
function increment(){
  value++;
}

This may seem simple enough, but already it can cause problems. If you want to make sure, pass everything as an argument. And I mean everything: I ended up even passing the window object as argument. It may seem slower at first, but the Tracer will work and usually take care of it.

var value=0;
function increment(value){
  return ++value;
}

To test this, I wrote my own little emulator (on the page you’ll also find results for Firefox, Chrome and Opera)… it doesn’t emulate a real machine, just some commands that I needed to implement a sample program: 16bit values, 64k memory, 4 registers plus overflow. Enough to bounce a ball around the screen and see how well the browser handles it using either a switch statement or function lookups.

The results are interesting: Firefox is actually fastest when it comes to pure processing (with the switch statement), followed by Chrome and far in the distance Opera. When you’re adding screen updates into the mix (timeouts) the picture changes a bit: Opera now takes first place since it’s able to use the whole timeout period to calculate ahead, but that’s because my sample program is very short. It wouldn’t be enough for a GameBoy emulator.

Firefox 4 AppTabs : Preparing with dynamic favicons

Firefox 4 is rapidly approaching release and there are numerous interface enhancements already included in the current nightlies. One is the addition of AppTabs; sticky tabs that remain at the left of your tab bar that are meant to serve as a place to keep your web “applications” like GMail or Twitter.

There’s still a lot that hasn’t yet determined about AppTabs yet, like how navigation is handled, when a link will open in the AppTab and when in a new tab and so on, but that it will only display the favicons with no title is reasonably certain. Since all your user will see of your website is a favicon it’s important to keep the user up-to-date using only this limited space, for example by showing the number of unread mails as part of the favicon.

This may seem like a difficult task, but thanks to Canvas it’s actually very simple. Assuming you already have a function somewhere in your code that gets notified when the number of new events changes, all you have to do is add code to that function that will create a Canvas, draw the number to it, remove the old favicon, create a new one and finally set it to the url you get from Canvas’ toDataURL.

One by one:

assuming you have a function onNewEvent(newEvents){} that is called with the number of events

function onNewEvent(newEvents){
  /* Create a canvas to draw the icon */
  var c=document.createElement("canvas"); 
  c.height=c.width=16; 
  var cx=c.getContext("2d"); 

  /* Formatting */
  cx.font="18px bold Calibri";
  cx.fillStyle="#000";

  /* Draw nothing if number is 0, "9+" for 10
    or more, otherwise the number */
  if(newEvents)
    cx.fillText(newEvents>9?"9+":newEvents,0,16,16); 
}

This will create a Canvas with the content we want (you’ll probably want to draw your usual favicon in the background as well and make the text a bit prettier, but this works for now). Now we need to assign it

For some reason setting the href value on an existing link[rel=”icon”] element doesn’t have any effect, so we have to create a new one to replace the existing one. First, let’s remove the old one(s):

  var oldicons=document.querySelectorAll(
    'link[rel="icon"], link[rel="shortcut icon"]'); 
  for(var i=0;i<oldicons.length;i++)
    oldicons[i].parentNode.removeChild(oldicons[i]);

And finally we create a new one and attach it to the head.

  var newicon=document.createElement("link"); 
  newicon.setAttribute("rel","icon"); 
  newicon.setAttribute("href",c.toDataURL()); 
  document.querySelector("head").appendChild(newicon);

The whole function now looks like this:

function onNewEvent(newEvents){
  /* Create a canvas to draw the icon */
  var c=document.createElement("canvas"); 
  c.height=c.width=16; 
  var cx=c.getContext("2d"); 

  /* Formatting */
  cx.font="18px bold Calibri";
  cx.fillStyle="#000";


  /* Draw nothing if number is 0, "9+" for 10
    or more, otherwise the number */
  if(newEvents)
    cx.fillText(newEvents>9?"9+":newEvents,0,16,16);

  /* Remove old icons and add node for new
    one (just setting the href won't work) */
  var oldicons=document.querySelectorAll(
    'link[rel="icon"], link[rel="shortcut icon"]'); 
  for(var i=0;i<oldicons.length;i++)
    oldicons[i].parentNode.removeChild(oldicons[i]); 
	
  var newicon=document.createElement("link"); 
  newicon.setAttribute("rel","icon"); 
  newicon.setAttribute("href",c.toDataURL()); 
  document.querySelector("head").appendChild(newicon); 
}

That’s all there is to it. No big framework, just a good dozen lines of code and you’re set.

Here’s a bookmarklet that will let you try it on GMail now. It’s Firefox-only since it hooks into GMail using the Gecko-only __defineSetter__ method on the title, but that’s only for the wrapper. The actual code works on any browser as long as it supports Canvas. Just drag this link to your bookmark toolbar, then click it while you’re using GMail (it will persist for your current session, but not if you refresh, restart and so on)

FireStation: Firefox on (an unhacked) PSP

Note: this is (for now) released under a proprietary license. You are allowed to install and use this on any number of systems, however you are not allowed to distribute it. As usual, it comes with absolutely no warranty. Should local raw require any warranty, then you are not allowed to download or use. The license thing is simply because I don’t want to see clones popping up yet. I didn’t submit it to the Mozilla Addon Directory because I don’t feel it’s ready yet and I don’t want others to do it instead. If you really do want to polish it to the point where it would be ready for mainstream use, drop me a line.

Source and installation (FireStation.xpi): Link (only tested in Firefox 4 betas so far).

Install it (and restart Firefox), then choose Tools/FireStation on the Firefox menu (make sure you don’t have any other web servers running). Finally, navigate to your PC’s IPv4 address using your PSP. You can find it by opening a command prompt and running “ipconfig” (should look similar to 192.168.2.86). Make sure that your router is configured to not expose port 80 to the outside world, since there is no authentication inside FireStation yet.

Thanks first to the good people over at the moznet #extdev channel, without whom I would never have gotten the Firefox sockets API to work properly.

OK, now on to the description to what this actually is: This Firefox Addon lets you remote control your Firefox from any PSP. It works by implementing a simple HTTP server with sockets, then feeding an it screen captures (generated with Canvas, drawWindow and toDataUrl), while sending scrolling, clicks and keystroke data back from the PSP to the PC and simulating it there.

It’s not optimized in any way, but it works surprisingly well already (for reading; it’s not exactly perfect as a video player). You can scroll using the PSP Square-button and Firefox will capture the rectangle you’re currently looking at and transmit that, instead of forcing you to fiddle around with scrollbars. There’s a location bar that you can click to enter a new location and a simplified keyboard that you can use for anything on the page, like search fields. There’s no right click, or support for multiple windows yet (they will open, but you won’t see them on the PSP).

The PSP browser (NetFront) is a user’s (and developer’s) nightmare, so the challenge here was twofold:

  1. Getting Firefox to work as a webserver
  2. Getting Netfront to show it

It may seem like getting the webserver running would be the hard part, but getting NetFront to behave is actually a good deal harder. The webserver is contained in a few easy to use classes in content/server.js. To use it, you simply throw it a configuration object and that’s that:

new HttpServer({
  "/screen":function(req){
    var res=new HttpResponse("","text/html");
    ...
    return res;
  },
  "/blank":new HttpResponse("empty","text/plain")
},80);

With Netfront, there is nothing easy or clean. Any code that is supposed to run on it will inevitably turn into one huge hack.

  1. There are no frame url setters, like myIframe.src=”http://www.google.com”. While it won’t throw an error, it simply won’t do anything
  2. No XMLHttpRequest. Not much of a surprise, but still inconvenient.
  3. Very little event support (no scroll or even a good load event).
  4. Very strange CSS/JS interaction (it doesn’t try to apply all CSS at once like normal browsers, but will update the screen between commands)
  5. Only a modal keyboard
  6. No way to create or remove any elements, other than document.write
  7. Tons of other stuff that I have forgotten about.

You overcome #1 and #2 using the legacy frames API, window.location and JS callbacks. #3 requires you to basically recheck manually from time to time and #4 simply means shuffling your CSS-applying JS code around until you get what you want. #5 is annoying because if you need to have something onscreen while the user is typing, you need to create your own and finally #6 means that you’ll be hacking around with iframes where you’d normally have a DIV, since that’s the only way to actually create new nodes.

This basically works, but it’s going to take a lot more hacking to make it pleasant to use. Clicks and Key-presses are ridiculously slow so far since the image takes up nearly all bandwidth, even when it’s transmitting the same image over and over again (detecting mozAfterPaint could fix this). Dynamic zoom and multi-tab support are really musts at some point as well.

Security: GMail vulnerability: Arbitrary script execution with SVG

Note: this vulnerability has long been fixed. I was just waiting for the confirmation from Google.

I could now tell a story of magic and wonder, how I spent day and night analyzing GMail and finally after weeks of hard work found this vulnerability. But the truth is that I was simply using GMail as I usually do when I came across this vulnerability.

GMail has had the “View Image” functionality for a while and I’ve often lamented that it doesn’t extend to SVG documents, which are eventually viewed through Firefox anyway. So when I finally noticed the “View Image” link next to an SVG that I had sent to my address for quick access on another computer, I happily clicked on it and was more than a little surprised when it opened on the mail.google.com domain.

You see, hosting any kind of unknown document on your own domain is extremely risky. Even a seemingly harmless PNG or JPEG can be a threat unless you really verify that it is what it claims to be and/or serve it from an unpredictable location. If it’s not and you didn’t notice, then all it takes is a browser trying to act smart and ignoring the MIME type for an attacker to take complete control of the user’s account. SVG is especially dangerous since, just like HTML, it can contain or link in script code. So, seeing the SVG open on mail.google.com was worrying.

On the other hand, GMail also displays HTML on mail.google.com by preprocessing it and removing anything that is not text or formatting-related (which is also an extremely dangerous task since every new release of a web browser includes new ways to load remote data, but apparently Google feels that it’s worth the risk: even allowing the loading of CSS can cause code execution), so there was some hope.

The problem is that in difference to HTML it is nearly impossible to preserve the majority of information in an SVG document if you strip it of tags that can be used to include data, since a lot of SVG’s core functionality relies on linking in fragments that can either be part of the local or any other document.

I started throwing some slightly obfuscated SVGs at it and was surprised to find that it didn’t filter any code at all, no matter how it was included. Using this knowledge and another attack vector (that I’m not going to describe yet since it’s still being worked on) I was able to deliver a harmful mail and open it by leading the user onto a specifically created webpage. With a bit of other black magic I was able to read the address book and all mails from there and have them delivered to my doorstep.

There’s not much more to this story. I reported it, the “View Image” link got disabled for SVG documents and we’re safe once again. But how can such a big issue ever slip through the cracks of Google’s testing and could this happen elsewhere? Well, I can only guess, but this is what it looks like from my perspective:

When you create any kind of software that may be an attack target, you define how potentially dangerous each component is. This may happen informally by people simply watching changes in certain files more closely or through a dedicated process that requires additional reviews for files marked “critical”, but it always happens.

So, how would you rate a file containing a list of image file formats, especially when there are only non-interactive formats like GIF, JPEG or PNG around (as was the case when GMail was initially created)? You’d probably mark it as “safe” and allow patches with minimal or no reviewing. Now, someone learns about this new “image format” SVG, not realizing that it is in fact a document format and adds it to the list of image files and voilà, you’ve got a class A untrusted code execution vulnerability.

What can we learn from this?

  1. Anything that ends up serving untrusted content from your servers really is security relevant
  2. Any assumption on the danger of a particular action should be rechecked regularly, to see if it still applies
  3. A little knowledge is a dangerous thing when it comes to file formats
  4. When in doubt, serve untrusted content from a separate domain.

Thanks to Adam from the Google Security Team for the good cooperation and being an all-around nice guy 🙂