PDA

View Full Version : JSON encode bug



harish
6 Feb 2007, 5:39 AM
Trying to encode an object which has nested object + array structures, I came across a condition where sometimes an array type is encoded like an object type.

[Note: Happens only sometimes.. couldn't exactly find out when.. might be something related to my system settings
- Windows xp sp2
- FireFox 2.0.0.1]

Bug description:

Occassionally the line of code inside "encode" method of YAHOO JSON namespace
that detects whether an object is an Array or not .. misses to detect that its indeed an array.

Correction that resolved the issue.

1. Add an additional arrayChecking function in the "encode" method as below


else if(o instanceof Array || adl_ArrObjChk(o)){

2. Additional check implementation


function adl_ArrObjChk(obj)
{
if (obj.length)
{
try{
tmpTest = obj.join(',');
return true;
}
catch(tmpErr)
{
return false;
}
}

return false;
}

Condor70
6 Feb 2007, 6:26 AM
Douglas Crockford (creator of JSON) has it's own isArray function:


function isArray(v) {
return v && typeof v === 'object' && typeof v.length === 'number' &&
!(v.propertyIsEnumerable('length'));
}

(I assume he knows best...)

tryanDLS
6 Feb 2007, 7:25 AM
Can you post an example? Are you sure this isn't a case of a mis-declared empty array, for example


{myArr:null} // wrong
{myArr:[]} // correct

harish
6 Feb 2007, 9:28 PM
Douglas Crockford (creator of JSON) has it's own isArray function:

ok. but i didnt find such a method inside YAHOO.JSON... does YAHOO.JSON use the same code as crockford's JSON... I feel YAHOO.JSON was improved and better than the original because crockford's json convertor didn't convert all of my nested object structure...it just kind of ignored some inner structures.


Can you post an example? Are you sure this isn't a case of a mis-declared empty array, for example

no. its not a mis-declared empty array. i verified it debugging inside the encode() method, trying its length and a few other tests. also, instead of making a string like [ {...}, {...} ], it made { 0: {...}, 1: {...} } for the array when it misinterpreted it as an object.

I will see how to post a sample.. since its a large object thats being converted.. and only during the conversion i find the problem.. the object structure in itself is the same.
i think i will have to post one proper, and one misconverted object string...will that help compare.

jack.slocum
8 Feb 2007, 1:07 AM
If that is your return value, then it's not an array. Check your declaration and be certain.

I don't know what crockford is doing, unless he is trying to support "Array-like" structures, or people who have extended Array.

The check looks like this:

o instanceof Array

and it comes right after the null check - so there's no way that can fail to detect an array. :)

harish
8 Feb 2007, 4:21 AM
I found a thread in another forum that addresses when instanceOf Array can fail..



at: http://www.thescripts.com/forum/post305236-2.html

When you say 'Array', you are talking about 'window.Array'. 'window' is the
browser's context object, and you get one per page (or frame). All of the arrays
created within a context will have their constructor property set to
'window.Array'.

An array created in a different context has a different window.Array, so your
test

myArray instanceof Array

fails.

I think that's exactly my problem. I have an iframe window inside my main window, through which the parent array object's value is set (sometimes set from the parent window itself.. that explains why it happened sometimes)

Interesting.. more interesting was that the thread message's author was crockford himself :)

Animal
8 Feb 2007, 4:37 AM
Might have use the test



if (obj.constructor.name == "Array")


to see if it's an Array.