How the bug found in IE9 Platform Preview caused a change in the Javascript standard
- Transfer
When we first unveiled our plans for pre-release versions of IE9, we said that “developers and people interested in standards and web development will be able to try out the pre-release version of IE9 and provide feedback and suggestions regarding its work.” At the moment, we receive daily reviews and use them to improve Internet Explorer 9. However, feedback sometimes applies not only to IE9. This story is about how a recent review on Internet Explorer 9 Platform Preview caused a change in the new JavaScript standard - the 5th edition of EcmaScript .
The EcmaScript 5 standard was officially adopted in December 2009, and the third preview version of Internet Explorer 9 is our first most comprehensive implementation. ES5 was designed to remain fully compatible with existing sites, and the TC39 technical committee worked to avoid any non-security related changes that could render the existing JavaScript code unusable. However, nothing perfect happens in the software world, and when we released the third preliminary version of Internet Explorer 9, we wondered if there would be any compatibility issues with existing sites related to ES5.
Shortly after the release of the preliminary version of our browser, we received several complaints that some web applications using jQuery did not work correctly in IE9. We found out that the problem was in the following jQuery API method , which in some cases did not work, because the method code before the call
Object.prototype.toString
did not check the value passed by the user to null
or undefined
. In particular, some calls to this jQuery methodisFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
}
* This source code was highlighted with Source Code Highlighter.
completed exception
“TypeError: Object expected”
. Further analysis showed that it was toString
a built-in method Object.prototype.toString
that caused a failure when it isFunction
called with a value undefined
as an argument. Why did this exception occur only in IE9, and not in earlier versions of IE, as well as in browsers of other manufacturers? Precisely because the behavior of the third pre-release version of IE9 in standard mode really complies with the ES5 specification Object.prototype.toString
. According to the previous EcmaScript specification, calling an inline method with a parameter
null
or undefined
results in the transfer of a “global object” (in browsers, this is a DOM objectwindow
) This opens up a number of potential security holes for frameworks whose purpose is to ensure that web applications work in safe mode. The ES5 specification has changed this behavior so that passing
null
or undefined
does not result in passing to an object function window
. The definition of each built-in method has been updated specifically to solve the problem of getting these values as a value this
. The technical committee attempted to maintain backward compatibility for normal use and throw an exception when this is not possible. This created the compatibility issue described above. This problem can simply be solved by changing the jQuery code:
isFunction: function( obj ) {
return obj && toString.call(obj) === "[object Function]";
},
* This source code was highlighted with Source Code Highlighter.
In fact, the jQuery team plans to make this change. However, this change will not affect the thousands of locally used jQuery libraries that exist on the web. Given the widespread use of jQuery, it becomes apparent that the ES5 specification contains a serious compatibility issue. It is also quite obvious how we can change our ES5 implementation in IE9 to solve the problem. We can just return the string value
"[object Object]"
, IE8 returns the same value in this situation. This fix does not add the security problems that ES5 is trying to solve. However, we do not want to unilaterally introduce such a difference in our implementation of the new standard. This solution will not help solve compatibility and interoperability problems.if IE fixes this problem in one of the ways and other browsers don't fix it at all or do it differently. As soon as we figured out the problem and the possible solution, I raised this issue on the discussion mailing listCommittee TC39. My first report on this issue was published at 5:51 pm on Friday, June 25th. By 10 pm, replies had already been received from TC39 members representing Apple, Mozilla, and Google. We all agreed that this was a compatibility issue that needed to be addressed, and throwing an exception in this case was neither necessary nor desirable. Initially, we agreed that the idea of returning a string value, as written in ES3, for such cases looks like a good idea. However, during further discussion at the weekend, we realized that not all browsers are currently returning
"[object Object]"
, we also considered the following values "[object Window]"
and "[object Global]"
. It was proposed to return
"[object null]"
and"[object undefined]"
. This solution seems to be the best, because it not only eliminates the problem, as in the case of jQuery, but also allows you to explicitly distinguish between undefined and null objects. This solution also increases the interoperability of browsers because it requires that browsers produce the same result, not an ES3 situation, which leads to different results in different browsers. On Tuesday, this decision was adopted by consensus as final. As soon as agreement was reached, I passed the revised specifications
Object.prototype.toString
to the IE9 JavaScript development team so that they could fix the current implementation before publicly testing the next preliminary version of IE9. Mozilla also confirmedthat will accept this fix in the next beta version of Firefox. I also updated the official TC39 patch list for ES5 ; this change is described in section 15.2.4.2 of the specification.Web standards are complex software artifacts, and like all software, they contain bugs. Sometimes the best way to find and fix a compatibility bug is to implement the standard in a widespread browser. This method is usually used in the context of the release of earlier versions of the browser, as is the case with Internet Explorer 9 Platform Preview. Thus, when you, as a web developer, send feedback to any particular browser, you also give feedback to the standards that it implements. Of course, in this case, browser authors and standard writers should be able to quickly respond to the problem. Fast response to ES5 problem
Object.prototype.toString
as well as other inconsistencies, a good example of how browser developers and other TC39 members can and do work together to provide a compatible and interoperable web. But it all starts with your feedback, which we are always happy. -
Allen Wirfs-Brock
Microsoft JavaScript Language Architect