How IE9 Platform Preview Feedback Changed the JavaScript Standard


When we first introduced our plans for Internet Explorer Platform Previews we said that “developers and people interested in standards and web development can try out new platform functionality and provide early feedback.” We are now getting such feedback on a daily basis and are using it to improve IE9. However, sometimes the impact of the feedback extends beyond just IE9. Here is the story of how some recent feedback regarding the third IE9 Platform Preview resulted in a correction to the new ECMAScript 5th Edition (ES5) standard for JavaScript.

The ES5 standard became official in December 2009 and the third IE9 Platform Preview is the first widely distributed implementation of some subtle details of the ES5 specification. ES5 was designed to be highly compatible with existing websites and the Ecma International TC39 technical committee worked to avoid any non-security related changes that might break existing JavaScript code. However, perfection generally does not exist in the world of software so with the third IE9 Platform Preview we were very interested to see if any ES5-related compatibility problems with existing sites would show up.

Soon after releasing this platform preview, we received reports that some web-apps that use the jQuery framework did not work correctly in the preview. We tracked the problem to a specific jQuery API method that in some cases passed a caller provided value to Object.prototype.toString without first checking if the value was null or undefined. Specifically, some calls to this jQuery method:

isFunction: function( obj ) {
     return toString.call(obj) === "[object Function]";
},

failed with an exception: “TypeError: Object expected”. Further analysis showed that toString in the above code was the built-in method Object.prototpe.toString and that the failures occurred when isFunction was being called with undefined as its argument. Why does an exception occur in IE9 and not in previous versions of IE or other browsers? It is because the third IE9 Platform Preview in standards mode actually conforms to the ES5 specification for Object.prototype.toString.

According to the prior editions of the ECMAScript specification, calling any built-in method using null or undefined as the this value passes the “global object” (in browsers this is the DOM window object) to the method as its this value.  This opens a number of potential security holes for frameworks that aim to support mash-ups in a secure way.

The ES5 specification changed this so that null or undefined is not replaced with the window object and the definition for each built-in method was updated specifically to deal with receiving these values as their this value. The ECMAScript technical committee tried to do this in a way that preserves backwards compatibility for normal usage and throws an exception in cases where that is not possible. Object.prototype.toString was specified in ES5 to throw such an exception. This created the compatibility problem described above.

This problem can be easily corrected by modifying the jQuery code with the additions shown in red:

isFunction: function( obj ) {
     return obj && toString.call(obj) === "[object Function]";
},

The jQuery team actually intends to make this change. However, such a change will not correct the thousands of locally hosted copies of jQuery that already exist on the Web. With the broad use of jQuery, it is clear that the ES5 specification contains a significant compatibility problem. It is fairly obvious how we can modify the IE9 ES5 implementation to eliminate the problem. We can just return the same string value ("[object Object]") that IE8 returns in this situation. Such a fix does not reintroduce any of the security problems that ES5 strives to eliminate. However, we do not want to unilaterally introduce such a variation into our implementation of a new standard. It does not help either compatibility or interoperability if IE fixes this problem one way, and other browsers either don’t fix it or fixed it a different way.

As soon as we understood the problem and the possible solution, I raised this on the TC39 es5-discuss mailing list as a backwards compatibility issue.  My first post on the issue went out at 5:51 PM on June 25, a Friday. By 10 PM there were responses from TC39 members representing Apple, Mozilla, and Google. We all agreed that this was a compatibility issue that needed to be fixed, and that in this case throwing the exception was unnecessary and undesirable. We also initially agreed that the idea of returning the same string value as ES3 for these cases sounded like a good idea. However, in further messages over the weekend we realized that browsers currently don’t all return "[object Object]" in this situation, some other values that were observed include "[object Window]" and "[object Global]". A proposal was made to return "[object null]" and "[object undefined]". This seemed to be a better solution as it not only fixes use cases such as jQuery’s but it also explicitly distinguishes null and undefined from actual objects. It is also better for browser interoperability because it requires that all browsers produce identical results rather than the ES3 situation that allowed different browsers to produce different results.

By Tuesday, the consensus on the mailing list was to follow this final proposal. As soon as that agreement was reached, I passed the revised Object.prototype.toString specification on to our IE9 JavaScript development team so they could make the fix in time to widely test it with the next IE9 platform preview build.  Mozilla has also indicated that they will be incorporating this fix into a future Firefox beta. I also updated the official TC39 Erratum for ES5  so this specification change is recorded there (section 15.2.4.2).

Web standards are complex software artifacts and like all software, they contain bugs. Sometimes the best way to find and fix compatibility bugs is to implement and deploy the standard on widely used browsers. This generally takes place in the context of early releases such as the IE9 platform preview builds. So, when you as a web developer are providing feedback on such releases you aren’t just providing feedback on a specific browser you are also providing feedback on the new and emerging standards that it implements. Of course, for this feedback to be worthwhile, browser implementers and standards authors need to be able and willing to quickly respond to feedback that identifies significant problems. The rapid response to the ES5 jQuery toString problem and other issues on es5-discuss show how browser implementers and other TC39 members can and do work closely together to create a more compatible and interoperable Web. But it all starts with your feedback, so please keep it coming.

Allen Wirfs-Brock
Microsoft JavaScript Language Architect

Comments (43)

  1. FremyCompany says:

    Nice explaination. Though I'm unsure why you are going to return [Object undefined] while the type of the 'undefined' value is 'Undefined', as stated in the ES5 spec. Same goes for 'null' whose type is 'Null'. To be consistant, you should return "[Object Undefined]" and "[Object Null]", or is there any reason why you should not ?

  2. Peter says:

    That was a very refreshing look at the standards process. Good post.

  3. h says:

    If this was released on XP, maybe it would have been found earlier.

  4. Dave C says:

    @h – IE9 Platform Preview 3, the first to have this EcmaScript5-defined behavior, was released on Wednesday, June 23. The problem was discovered and analysed and a potential solution submitted to the es5 mailing list by Friday, June 25.

    Just how much earlier do you think it would have been found if the previews were released on XP? A few minutes? Maybe an hour?

  5. Mike Taylor says:

    Object.prototpe.toString is like, totally a typo.

  6. Mitchum says:

    Good to see you working with other browser vendors to come to a consensus.  I'm ok with any outcome that is agreed to by all.

    So, is IE9 going to return something more useful in JavaScript errors that appear in the browser (bottom left corner)?

    Object does not support property or method….. Or whatever it says without giving any indication what object or what property is really annoying.  The dialog also needs a clear button. Next and previous buttons are also useless Esp. If the dialog is fixed to show a real, scrollable list.

  7. Offbeatmammal says:

    @Mitchum (and maybe Allen can help broker this…)

    the little yellow error sign can be trapped and managed in IE and Firefox using the window.onerror handler (eg using a script like http://jserrlog.appspot.com/ ) but… sadly Webkit (Chrome and Safari) and Opera don't support this (as noted in the comments on that link) because they would prefer to argue that the de facto spec isn't good enough so rather than support it (and maybe offer up a better suggestion) they'll just break scripts… jQuery have since given up trying to help developers trap unexpected errors and degrade gracefully because of this.

    Would love to see Webkit follow IE and Firefox on this as I can see with more javascript coding rather than less coming hand in hand with the HTML5 improvements a way to manage this gracefully is going to become more important, not less.

  8. Mike says:

    A very interesting post and maybe a reflection of how powerful jQuery has become that the ECMAScript specification is changed so as not to the break jQuery code.

    The widespread adoption of various JavaScript libraries should mean less sites break on the release of new browsers.

    A good solution from all concerned.

  9. jabcreations says:

    IE, Firefox, Opera, and Safari all have their own respective strengths when it comes to their JavaScript error consoles. In particular is Opera's JavaScript trackback feature because unfortunately there are instances where yes, somehow I've managed to send a null or undefined string to a function through a parameter and I'm not aware of which function called the function that spawned the error. IE is pretty good about catching errors at least and is reasonably strict like Firefox however Firefox doesn't catch everything either. Safari is good about catching things like incorrect media types/mimes. That's why I thoroughly test scripts with all four browsers. Any way adding a trackback feature (unless it now exists and I've missed it at some point?) so I can see the name of function a that sent a parameter to function b that was null or undefined would resolve 90% of the errors I encounter; not that it's a high count to begin with of course. 😉

  10. EricLaw [MSFT] says:

    @jabcreations: If you're running with script debugging, you can simply view the "Call Stacks" tab on the Script Debugging tab on the F12 developer tools.

  11. wai says:

    some browsers allow user to stop futher javascript alert, which help to stop some websites' annoying alert, would IE consider to add this function?

  12. Wurst says:

    typeof null === 'object'

    There you go!

  13. jabcreations says:

    @EricLaw [MSFT] Awesome, thank you!

  14. frymaster says:

    apologies for the drive-by offtopic question, but seen as how this blog is active and the RSS teams' isn't… are there any changes to the way RSS feeds work planned? specifically, at the moment, all data about feeds is kept in the local part of the user profile.  This means you lose your RSS subscriptions if you change PC.  A workaround is to use outlook, which monitors the RSS store for feeds, and copies them into its own RSS system.  But I prefer to read my feeds in IE, since in most cases I'm going to end up clicking through to the website anyway.  From my point of view, changing at least the feed URL & preferences, and enough data to be able to work out what counts as an unread article, to be part of the roaming profile, would be fantastic.

    Again, apologies for the OT comment on something that's only half related to the blog 😉

  15. FremyCompany says:

    @frymaster : Nice idea. I would suggest you to use the contact form of the blog, though, as your proposal don't seem to find its right place here.

  16. Olivier Mengué says:

    Up to IE8, the JavaScript engine that comes with IE is also used in the Windows Script Host (WSH) environment.

    Could you confirm that installing IE9 will bring those ES5 features to WSH?

    Is it already the case when installing the IE9 preview?

    Does your javaScript test suite test the engine in WSH too?

  17. EricLaw [MSFT] says:

    @Olivier: Installing the IE9PPB wil not change the script engine used by WSH. I don't think the JavaScript team has yet announced any plans for use of the new engine by non-Web Browser hosts.

  18. console says:

    does console.log(msg); work in IE9 yet?

  19. EricLaw [MSFT] says:

    @console: The statement console.log(msg) has been supported since IE8. It's important to note, however, that the console object is only non-null while the Developer Tools are in Script Debugging mode.

  20. David says:

    @console: The real question is will we be able to see ajax post data? console.log also sucks in IE because it will only tell you that you are logging an object. It won't show you the innards of the object.

  21. EricLaw [MSFT] says:

    @David: You should probably try the Platform Preview build. The Network Monitor tab shows AJAX POST data. To log "the innards" of an object, you can simply stringify the object using the JSON object.

  22. FremyCompany says:

    @EricLaw : The problem with stringification is that it takes a lot of place in the console. The why Firebug handle it is way better because we can click on the log and navigate through the object's properties in a popup window, if we need it. In other cases, we just get the result of the "toString" stringification, which is usually short.

  23. Pat says:

    Loved this post!  As a web developer, it's very rewarding to see all the browser vendors tackling these kinds of problems together. Cheers to the good folks at Microsoft for taking the initiative, and cheers to the esteemed individuals involved in this case. 🙂

  24. speaking of specs says:

    I was reading up on HTML5 and was testing out the keygen element. dev.w3.org/…/Overview.html

    From WhatWG comments from 2009 (src=Adrian) blog.whatwg.org/this-week-in-html5-episode-35 it appears that Microsoft has no intention of meeting the HTML5 spec for this particular element.

    Can Microsoft please clarify if they plan to meet this – and if not, explain why? e.g. does MSFT see/know of some security issue that needs to be addressed?

    As you've identified in the past few blog posts – interoperable code that works across all browsers only works if all browsers support the same specs.  Just trying to figure out if MSFT is picking/choosing what standards it plans to follow or if this particular element needs more research/time to hash out all the details.

  25. hAl says:

    @speaking of spec

    The keygen element is a remenants of old Netscape junk that should not have been added to the HTML5 draft.

    It should be deprecated ASAP and replaced by a proper scripted crypto API solution and should not be in HTML at all. It should be quickly removed from the HTML5 drafts as not to promote further use which would make it more difficult to deprecate.

    There is no good reason for adding it to a standard.

  26. Mitch 74 says:

    @hAl: the HTML5 version of keygen seems rather complete to me… It's actually almost as big as ssh-keygen's man page. Only the default settings are weak (RSA+MD5), but that can be expected due to its Netscape history (for compatibility reasons), and it supports more. There is also information on MSDN about Netscape's KEYGEN support, so I'll venture a guess that 'keygen' might be supported by IE 9 later on.

    Moreover, if keygen had little to do inside HTML 4 and its definition as a static markup language, HTML5 fits the bill a bit more: it's supposed to be more dynamic.

  27. Matt says:

    Mitch: It's quite a leap to guess that IE will support KEYGEN only because legacy documentation on MSDN mentions this Netscape-era feature.

    Considering the complexity, privacy, and security impact, I would be very surprised to see support for this feature in IE, and would not be at all surprised to see it pulled from HTML5 when they decide that it might be nice to finish the spec before 2020.

  28. Johnnyq3 says:

    Question is it Google's progarming that is causing IE9 no to function with Google wave?

  29. marcus says:

    IE dev toolbar feedback.

    I got very annoyed today trying to do basic debugging in IE with the IE dev toolbar.  I'm aware that it pales in comparison to Firebug and other dev tools for other browsers but it really should get updated (and preferably not be tied to IE release dates!!!!)

    Bugs noted today thus far.

    1.) the "HTML search" in the top right doesn't find dynamically added HTML elements, attributes, etc.

    2.) When it doesn't find anything (or any more matches) it doesn't NOTIFY the user

    3.) The select by click tool doesn't work on some dynamically added elements (in particular, the jQuery inline calendar popup) (note they do appear if you force a refresh through the refresh button on dev toolbar)

    4.) The nesting of HTML elements is highly irregular compared to what developers are expecting – you have some sort of quazi tree thing going on sometimes children are nested, some times they flow after the parent – very, very confusing

    5.) I'm not sure where IE gets the HTML source from that it renders but it CERTAINLY isn't the source I generated from my server – totally invalid HTML and wonky CSS properties

    6.) why do the CSS properties not follow convention of property-name:{space}value? why is there a space before the colon? it makes it very hard to scan

    7.) Looking at the CSS styles (traced or otherwise) you can't add new properties (e.g. I want to add zoom or display to see if I can hack a fix for IE's rendering bugs)

    8.) On the attributes panel, if you add a style attribute (because you can't add a property (see above)) when you press enter after setting the value the toolbar lists the CSS property as an HTML attribute on the element (FAIL!)

    9.) The save HTML button opens up a file dialog with only an option to save a *.txt file (FAIL!)

    10.) The image toolbar sub options – other than disable, most don't work!

    11.) The image report opens up a report, but it contains bugs… the AdjustedHeight value is actually pointing to the AdjustedWidth property (the XSL that processes the XML file is correct, its the XML that is wrong) (PS the CSS in the XSL file includes an invalid property:value delimiter (line 29 "=" vs ":")

    12.) The image report includes every image… and does not filter out duplicates thus generates a massive (not worth printing) report.

    I realize that building a developer toolbar wasn't a Microsoft priority when the browser itself needed so much attention but this toolbar should be getting regular updates every 6 months or so if Microsoft really wants IE to be able to be used as a developer tool, not just as a secondary test tool.

  30. marcus says:

    continued rant

    13.) why do all my images, in the HTML source, have a complete="complete" attribute? WT_?!?!

    14.) HTML source claims "Empty text node" if source contains " " or UTF variants

    15.) Locking/Unlocking my (XP) PC causes the toolbox icons on the pinned toolbar to shift from far right to floating left beside the Document Mode status

  31. Paul says:

    Sorry for the OT, but is there any chance you can make IE9 store the temporary files in a cache file (like Firefox and Chrome), instead of "normal" clear multiple files and folders? The current IE's behaviour makes it so easy to recover files after deleting its browser history. Even if the files are actually fully/partially overwritten on the hard disk, you can always read their names using undelete/recovery applications (like Recuva for example). This change would enhance IE's privacy features.

    Thank you.

  32. EricLaw [MSFT] says:

    @Paul: An attacker with the permissions to recover your cache files could execute any of a number of related attacks, against not only IE but also Firefox, Chrome, or any other browser, even those that do not use individual cache files.

    If this is a "laptop loss"-style scenario, then you should use BitLocker full-disk encryption to prevent recovery of any disk data.

    If this is a "I'm later forced at gunpoint to log in as me and decrypt my disk" scenario, then you should follow up your cache file deletion with the DOS command cipher /w C: to wipe the free space on your disk. You might also want to configure the "wipe swap file" policy to ensure that the windows swap file cannot be recovered.

  33. Paul says:

    @EricLaw [MSFT]: Thank you for your reply. It was more a "computer shared with a friend"-style scenario actually. But the "laptop loss"-style scenario could work as well.

    Just out of curiosity, besides its intrinsic simplicity, is there any particular advantage to the IE's individual cache files over the single cache file?

  34. EricLaw [MSFT] says:

    @Paul: There are a bunch of tradeoffs between using a single-db-file and multiple individual files, related to performance, reliability, interoperability, etc. I don't think that one design is inherently better than other in all ways.

    The reason that IE has individual files is largely architectural– in the IE model, plugins/addons and traditional applications all expect to be able to operate on individual cache files directly within the cache. Hence, they expect a file to be there, and if it's not, they won't work properly. Now, clearly you could build a API model around allowing such code to be smart enough to read from the single-db-file, but then the plugins/addons/applications would all need to use the browser API to retreive data from the cache database rather than simply opening a file on disk. Not an insurmountable obstacle, but something that would make shifting from one type of cache to another non-trivial.

  35. Paul says:

    @EricLaw [MSFT]: I see, thank you for the explanation. 🙂

    Anyway, what about the index.dat files? Those are not even deleted by the various "delete browser history" commands available in IE, and they have to be deleted by third parties' scripts/applications such as CCleaner. It would be nice if IE could delete those files through an option the same way it deletes temporary files and cookies.

  36. EricLaw [MSFT] says:

    Paul: Index.dat files aren't deleted but what's not obvious is that the Delete Browser History command fully overwrites the contents. That prevents undeletion of the file, since the file is still present, but has been completely wiped.

  37. Vic says:

    @Paul – the cache files as seperate files vs. 1 DB and likewise the bookmarks as seperate files vs. 1 file is why things take sooo long in IE (e.g. deleting a shortcut takes forever)

    Likewise bookmarklets suck in IE because they are architecturally limited to the filename length rather than string links inside an html/xml file.

    then again, the chrome in IE9 is still under wraps – so maybe they've fixed this and all the other UI issues that IE suffers from.

  38. Paul says:

    @EricLaw [MSFT]: Actually, as you can see running Index.dat Analyzer (http://www.systenance.com/indexdat.php), the index.dat files in the following directories are not wiped when deleting browser history (IE8 on Windows 7 32-bit):

    C:UsersMyUserNameAppDataLocalMicrosoftFeeds Cacheindex.dat

    C:UsersMyUserNameAppDataLocalMicrosoftWindowsHistoryHistory.IE5MSHist_some_numberindex.dat

    C:UsersMyUserNameAppDataLocalLowMicrosoftInternet ExplorerDOMStoreindex.dat

    The index.dat files in the main history/temporary files directories are wiped though, as you explained. 🙂

  39. EricLaw [MSFT] says:

    You shouldn't expect deleting your browser history to clear your RSS feeds. For the DOMStore and History Containers, do you find anything interesting in those files after clearing your cache?

  40. Paul says:

    @EricLaw [MSFT]: I have no feeds actually. The ones reported in those index.dat files are old ones I deleted several weeks ago in IE.

    As for the DOMStore and History Containers, I do find the URL of various websites (such as something regarding Facebook Connect and the MeeboBar some sites/forums uses) I visited before clearing my cache, which are something I would expect to be wiped when deleting my browser history.

  41. Johnnyq3 says:

    Question is it Google's progarming that is causing IE9 not to function with Google wave?

    Based on this article, IE9 has better support for Javascript, but the page refuses to load.

  42. CvP says:

    I really like these blog posts but you haven't posted anything for some time now.

    /cry

    btw, I hope you have fixed the subsequent <a> elements getting hidden while an <a> element is highlighted.

    [started from PP3; test it here: http://www.bakabt.com/description.php ]

  43. Infinte says:

    @CvP: It is caused by the box-shadow.

    And this feature is currently under test.

Skip to main content