Loading ...
Sorry, an error occurred while loading the content.

IE8 Native JSON Bug

Expand Messages
  • Stephen M. McKamey
    We have been having a heck of a time with an issue in IE8 s implementation of JSON.stringify(). It appears that IE8 *sometimes* encodes an empty string as the
    Message 1 of 7 , Jun 1 1:35 PM
    • 0 Attachment
      We have been having a heck of a time with an issue in IE8's implementation of JSON.stringify(). It appears that IE8 *sometimes* encodes an empty string as the string "null". If anyone has a clean work-around for this, or at least an explanation I'd be really interested. Am I missing something?

      Here is the repro:

      var good = ""; // good === ""
      var bad = document.createElement("input").value; // bad === ""

      if (good === bad) {
      // this is the path followed
      alert("Strings: good === bad");
      } else {
      alert("Strings: good !== bad");
      }

      good = JSON.stringify(good); // good === '""' here
      bad = JSON.stringify(bad); // bad === "null" here

      if (good === bad) {
      alert("JSON.stringify: good === bad");
      } else {
      // this is the path followed
      alert("JSON.stringify: good !== bad");
      }
    • Ric Johnson
      IE may have a REFERENCE to the origianl object. In your first example, when coerced into a string from th LEFT, they are equivilant The stringify method may
      Message 2 of 7 , Jun 1 6:27 PM
      • 0 Attachment
        IE may have a REFERENCE to the origianl object.

        In your first example, when coerced into a string from th LEFT, they are equivilant

        The stringify method may convert t an OBJECT as null, since the element value is not actually set.


        --- In json@yahoogroups.com, "Stephen M. McKamey" <stephen@...> wrote:
        >
        > We have been having a heck of a time with an issue in IE8's implementation of JSON.stringify(). It appears that IE8 *sometimes* encodes an empty string as the string "null". If anyone has a clean work-around for this, or at least an explanation I'd be really interested. Am I missing something?
        >
        > Here is the repro:
        >
        > var good = ""; // good === ""
        > var bad = document.createElement("input").value; // bad === ""
        >
        > if (good === bad) {
        > // this is the path followed
        > alert("Strings: good === bad");
        > } else {
        > alert("Strings: good !== bad");
        > }
        >
        > good = JSON.stringify(good); // good === '""' here
        > bad = JSON.stringify(bad); // bad === "null" here
        >
        > if (good === bad) {
        > alert("JSON.stringify: good === bad");
        > } else {
        > // this is the path followed
        > alert("JSON.stringify: good !== bad");
        > }
        >
      • Stephen M. McKamey
        The triple-equals shouldn t be coercing the arguments before comparison. Reversing the order of the test to (bad === good) still results in true. To top that
        Message 3 of 7 , Jun 1 6:42 PM
        • 0 Attachment
          The triple-equals shouldn't be coercing the arguments before comparison. Reversing the order of the test to (bad === good) still results in true. To top that off, typeof returns "string" for both.

          The other thing that is odd is that even if it were treating the value as a null object, it should serialize as "null" but instead it actually serializes as the escaped string '"null"'. There was a typo in the repro, it should have read:

          bad = JSON.stringify(bad); // bad === '"null"' here

          What is scary about this, is that unless you fix it at the time of gathering the data off the input element, you have no way of differentiating between a real string and this bogus string which acts as if the user typed the word "null" into the input.

          --- In json@yahoogroups.com, "Stephen M. McKamey" <stephen@...> wrote:
          >
          > We have been having a heck of a time with an issue in IE8's implementation of JSON.stringify(). It appears that IE8 *sometimes* encodes an empty string as the string "null". If anyone has a clean work-around for this, or at least an explanation I'd be really interested. Am I missing something?
          >
          > Here is the repro:
          >
          > var good = ""; // good === ""
          > var bad = document.createElement("input").value; // bad === ""
          >
          > if (good === bad) {
          > // this is the path followed
          > alert("Strings: good === bad");
          > } else {
          > alert("Strings: good !== bad");
          > }
          >
          > good = JSON.stringify(good); // good === '""' here
          > bad = JSON.stringify(bad); // bad === "null" here
          >
          > if (good === bad) {
          > alert("JSON.stringify: good === bad");
          > } else {
          > // this is the path followed
          > alert("JSON.stringify: good !== bad");
          > }
        • Stephen M. McKamey
          Below is the answer from Microsoft about this bug in JSON.stringify. Thanks Douglas Crockford for forwarding on to the appropriate contact at Microsoft. It
          Message 4 of 7 , Jun 2 8:41 AM
          • 0 Attachment
            Below is the answer from Microsoft about this bug in JSON.stringify. Thanks Douglas Crockford for forwarding on to the appropriate contact at Microsoft.

            It appears the short answer is that you have to test for empty strings coming off DOM elements and replace with a real empty string. That can be done via the replacer function or at the time of retrieving the value.

            ---------- Forwarded message ----------
            From: Allen Wirfs-Brock
            Date: Tue, Jun 2, 2009 at 08:15
            Subject: RE: [Fwd: [json] IE8 Native JSON Bug]


            This is a bug in the initial production version of IE8 that we were already aware of. The problem is that within the DOM a special encoding is used to represent a missing string value. Even though this special value is different from the encoding of the JavaScript literal "", throughout the JScript implementation the value is treated as being === to "" ... except for one oversight in JSON.stringify.

            Since this special value only originates from accesses to DOM objects one workaround is to explicitly censor them on every DOM access that might return one. For example,
            var good, possiblyBad = good =document.createElement("input").value;
            if (possiblyBad === "") good = ""; //ensure possibly bogus "" is replaced with a real ""
            In particular, this should be done when accessing the value of an input element if that value is going to be assigned to a structure that will be passed through stringify.

            Since the difference is only observable via stringify, another alternative is to use the replacer function to perform the substitution:
            JSON.stringify(document.createElement("input").value,
            function(k,v) { return v==="" ? "" : v});
            //the above will return "", not "null"

            A post describing this problem and the workaround should appear on the JScript blog (http://blogs.msdn.com/jscript/ ) sometime this week.

            Allen
          • Stephen M. McKamey
            Allen Wirfs-Brock suggested another work-around to the IE8 native JSON issue: Another work-around that is isolated to a single place is to use IE8 s mutable
            Message 5 of 7 , Jun 2 1:24 PM
            • 0 Attachment
              Allen Wirfs-Brock suggested another work-around to the IE8 native JSON issue:

              Another work-around that is isolated to a single place is to use IE8's "mutable DOM prototypes" support to patch HTMLInputElement.prototype.value so that the bogus "" value is filtered out. For example:

              ...

              (function() {

              var builtInInputValue = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value").get;

              Object.defineProperty(HTMLInputElement.prototype, "value",

              { get: function() {

              var possiblyBad = builtInInputValue.call(this);

              return possiblyBad === "" ? "" : possiblyBad;

              }

              });

              })();

              ...

              A patch like this could be conditionally executed as part of the initialization code of a framework.
            • Arthur Blake
              Just saw this come across my automatic updates: http://support.microsoft.com/kb/976662 Perhaps Microsoft has fixed the
              Message 6 of 7 , Feb 25, 2010
              • 0 Attachment
                Just saw this come across my automatic updates:

                http://support.microsoft.com/kb/976662

                <http://support.microsoft.com/kb/976662>Perhaps Microsoft has fixed the
                problem??

                On Tue, Jun 2, 2009 at 3:24 PM, Stephen M. McKamey <stephen@...>wrote:

                >
                >
                > Allen Wirfs-Brock suggested another work-around to the IE8 native JSON
                > issue:
                >
                > Another work-around that is isolated to a single place is to use IE8's
                > "mutable DOM prototypes" support to patch HTMLInputElement.prototype.value
                > so that the bogus "" value is filtered out. For example:
                >
                > ...
                >
                > (function() {
                >
                > var builtInInputValue =
                > Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value").get;
                >
                > Object.defineProperty(HTMLInputElement.prototype, "value",
                >
                > { get: function() {
                >
                > var possiblyBad = builtInInputValue.call(this);
                >
                > return possiblyBad === "" ? "" : possiblyBad;
                >
                > }
                >
                > });
                >
                > })();
                >
                > ...
                >
                > A patch like this could be conditionally executed as part of the
                > initialization code of a framework.
                >
                >
                >


                [Non-text portions of this message have been removed]
              • Dennis Gearon
                Wonder about escaping characters using a JSON API. JSON isn t JUST for browsers obviously, (moblie apps or direct B2B) would be the starting list for other
                Message 7 of 7 , Feb 25, 2010
                • 0 Attachment
                  Wonder about escaping characters using a JSON API.

                  JSON isn't JUST for browsers obviously, (moblie apps or direct B2B) would be the starting list for other uses). But XMLHttpRequests in browsers are a large portion of possible use scenarios.

                  So - Is anyone escaping JSON content to prevent XSS from stored data? Are you storing it escaped?

                  Dennis Gearon



                  Signature Warning

                  ----------------

                  EARTH has a Right To Life,

                  otherwise we all die.



                  Read 'Hot, Flat, and Crowded'

                  Laugh at http://www.yert.com/film.php

                  --- On Thu, 2/25/10, Arthur Blake <arthur.blake@...> wrote:

                  From: Arthur Blake <arthur.blake@...>
                  Subject: Re: [json] Re: IE8 Native JSON Bug
                  To: json@yahoogroups.com
                  Date: Thursday, February 25, 2010, 12:59 PM







                   









                  Just saw this come across my automatic updates:



                  http://support. microsoft. com/kb/976662



                  <http://support. microsoft. com/kb/976662>Perhaps Microsoft has fixed the

                  problem??



                  On Tue, Jun 2, 2009 at 3:24 PM, Stephen M. McKamey <stephen@jsonfx. net>wrote:



                  >

                  >

                  > Allen Wirfs-Brock suggested another work-around to the IE8 native JSON

                  > issue:

                  >

                  > Another work-around that is isolated to a single place is to use IE8's

                  > "mutable DOM prototypes" support to patch HTMLInputElement. prototype. value

                  > so that the bogus "" value is filtered out. For example:

                  >

                  > ...

                  >

                  > (function() {

                  >

                  > var builtInInputValue =

                  > Object.getOwnProper tyDescriptor( HTMLInputElement .prototype, "value").get;

                  >

                  > Object.defineProper ty(HTMLInputElem ent.prototype, "value",

                  >

                  > { get: function() {

                  >

                  > var possiblyBad = builtInInputValue. call(this) ;

                  >

                  > return possiblyBad === "" ? "" : possiblyBad;

                  >

                  > }

                  >

                  > });

                  >

                  > })();

                  >

                  > ...

                  >

                  > A patch like this could be conditionally executed as part of the

                  > initialization code of a framework.

                  >

                  >

                  >



                  [Non-text portions of this message have been removed]






















                  [Non-text portions of this message have been removed]
                Your message has been successfully submitted and would be delivered to recipients shortly.