2009-09-23 16:34:59 UTC
Consider trying to xmlize the following:
var Container = function(type, region) {
this.type = type;
this.region = region;
this.items = null;
};
var test = new Container('container-type-1', 'east');
test.items = new Array();
test.items[0] = new Container('container-type-embedded', 'center');
test.items[1] = new Container('container-type-empty', 'south');
var testxml = Sarissa.xmlize(test, 'test', ' '); // CAUSES ERROR
The xmlize statement (last line) will cause a stack overflow exception, seen as "out of stack space"
in IE and "Too Much Recursion" in Mozilla.
This is because xmlize tries to serialize the method: remove() on the array item and this causes a reentry into the recursive method. Methods never resolve to leaf-nodes and cause infinite recursion.
Sarizza.xmlize should not xmlize methods but rather only variables. Therefore, we need to check for this condition. We can do this by placing a check below that an object's member is never an instanceof type Function. The code change is the 3 extra lines well commented within the for loop.
When we run the above code again (using the new xmlize function) we no longer get an error and can recurse much more complex object structures.
Sarissa.xmlize = function(anyObject, objectName, indentSpace){
indentSpace = indentSpace?indentSpace:'';
var s = indentSpace + '<' + objectName + '>';
var isLeaf = false;
if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String
|| anyObject instanceof Boolean || anyObject instanceof Date){
s += Sarissa.escape(""+anyObject);
isLeaf = true;
}else{
s += "\n";
var itemKey = '';
var isArrayItem = anyObject instanceof Array;
for(var name in anyObject){
// *************************** NEW CODE START ******************************
if (anyObject[name] instanceof Function) {
continue;
}
// *************************** NEW CODE END ********************************
s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " ");
};
s += indentSpace;
};
return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");
};