a test for stringify "whitelist" which WebKit fails
This is a fairly recent (last couple months, I believe) change to the spec. The whitelist used to require strings. It now may contain strings, numbers, string objects, or number objects. They all get converted to string values. See stringify steps 4.b.ii.2-4.
Do we intend that
str = new String("foo"); str.toString=function(){ alert("Wiffle"); } JSON.stringify(..., [str])
will execute the custom toString?
Yes, when the spec. says ToString it really does mean to fully apply the ToString algorithms. This is a good test case to have.
I was looking at webkit's failure of test 004 and 005 -- clamping of
gap to 10 characters -- and it actually looks like you've missed out
step 8.b.iii "if gap is not the empty string" -- your regexp for
testing the result should have a space character following the colon.
On Fri, 28 Aug 2009 21:49:24 +0200, Oliver Hunt <oliver at apple.com> wrote:
Okay, the final list of issues:
Great feedback on the tests - thanks a lot!
correctness/010.js incorrectly expects the non-ascii characters to be escaped -- The abstract operation Quote only escapes ", , and the characters less than space. double-quote, backslash, backspace, formfeed, newline, carriage return, and tab get escaped as ", \, \b, \f, \n, \r, and \t respectively. The remaining control characters get the generic unicode escape.
correctness/037.js incorrectly expects JSON.stringify(undefined) to produe an empty string -- it is spec'd as producing undefined.
Both fixed.
correctness/045.js uses Number as the object to serialise, but Number is a function so does not get stringified - JSON.stringify(function() { return arguments; }(), ["length"]) should do.
Thanks - though funny that Safari is the only browser here that actually
passes the test. So Safari has a bug here? :)
integration/004.js makes Math.toJSON returns a stringified object instead of the new object itself,
If that's wrong, I've misunderstood how toJSON() is supposed to work
(thought it was meant to return a string representation of the object).
I see from the algorithm that the output of the toJSON() call goes through
the quote operation if it is a string and the JA/JO serializations if it's
array or object, but the spec does not really cover this issue in prose
anywhere?! It's a bit late for such feedback but the functionality of a
custom toJSON() method seems really underdefined.
integrity/004.js and 005.js have incorrect regexps as they fail to account for 8.b.iii "if gap is not the empty string"
Fixed.
From earlier E-mail:
Do we intend that
str = new String("foo"); str.toString=function(){ alert("Wiffle"); } JSON.stringify(..., [str])
will execute the custom toString?
Good question, now captured in this test:
testsuites.opera.com/JSON/integration/007.html
asserting that it should indeed use the custom toString(). Only Firefox
gets it right in this murky corner at the moment.
On Sep 1, 2009, at 7:39 AM, Hallvord R. M. Steen wrote:
correctness/045.js uses Number as the object to serialise, but Number is a function so does not get stringified - JSON.stringify(function() { return arguments; }(), ["length"]) should do.
Thanks - though funny that Safari is the only browser here that
actually passes the test. So Safari has a bug here? :)
Yes, because shipping Safari serialises function objects as ordinary
objects :-(
integration/004.js makes Math.toJSON returns a stringified object instead of the new object itself,
If that's wrong, I've misunderstood how toJSON() is supposed to work
(thought it was meant to return a string representation of the
object). I see from the algorithm that the output of the toJSON()
call goes through the quote operation if it is a string and the JA/ JO serializations if it's array or object, but the spec does not
really cover this issue in prose anywhere?! It's a bit late for such
feedback but the functionality of a custom toJSON() method seems
really underdefined.
toJSON returns the object that is expected to be serialised -- eg.
Date.prototype.toJSON returns an unquoted string. Step 2. of the
abstract operation Str handles toJSON as (basically)
if (typeof value.toJSON === "function")
value = value.toJSON();
integrity/004.js and 005.js have incorrect regexps as they fail to account for 8.b.iii "if gap is not the empty string"
Fixed.
You also need to check for the new line following every brace or
bracket, if there's a gap the output is multiline, so your regexps
should be
/{\n {10}"prop1": {}/ and /{\na{10}"prop1": {/
I'm curious about this TC - it appears to be WebKit against the rest of
us, but it will take me some assistance from somebody with Superior
Spec-Reading Skills to figure out who does the right thing..
testsuites.opera.com/JSON/correctness/046.html
(test code is at
testsuites.opera.com/JSON/correctness/scripts/046.js )
Issue: if an object has properties whose name is a number inside a string
({'1':'foo'}) and you pass in a white-list array to stringify(), WebKit
requires the elements in the array to be numbers inside strings too, while
other implementations allow either plain numbers or numbers inside strings.
The latter makes more sense to me given that JS generally doesn't
distinguish obj[1] and obj['1']. Do you think this is a WebKit bug?