PDA

View Full Version : "Safe option" in Ext.decode



Tom23
11 Aug 2009, 5:39 AM
From the docs (http://extjs.com/deploy/dev/docs/?class=Ext.util.JSON):


decode( String json ) : Object
Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError unless the safe option is set.
Can anyone please explain to me what "safe option" refers to?

11 Aug 2009, 5:47 AM
A very valid question.


30 doDecode = function(json){
31 return eval("(" + json + ')');
32 },
...
147 this.decode = function() {
148 var dc;
149 return function(json) {
150 if (!dc) {
151 // setup decoding function on first access
152 dc = isNative() ? JSON.parse : doDecode;
153 }
154 return dc(json);
155 };
156 }();

Condor
11 Aug 2009, 5:48 AM
I have no idea. The only setting that affects how Ext.decode works is Ext.USE_NATIVE_JSON.

11 Aug 2009, 5:49 AM
using firebug:


Ext.decode("{foo:'bar'", true)

fails

11 Aug 2009, 5:50 AM
Supporting code:

167 /**
168 * Shorthand for {@link Ext.util.JSON#decode}
169 * @param {String} json The JSON string
170 * @param {Boolean} safe (optional) Whether to return null or throw an exception if the JSON is invalid.
171 * @return {Object} The resulting object
172 * @member Ext
173 * @method decode
174 */
175 Ext.decode = Ext.util.JSON.decode;

Tom23
11 Aug 2009, 6:54 AM
So, either the source code of Ext.util.JSON should contain something like


this.decode = function() {
var dc;
return function(json, safeMode) {
if (!dc) {
// setup decoding function on first access
dc = isNative() ? JSON.parse : doDecode;
}
if (safeMode) {
try { // yes, I know this is ugly
return dc(json);
} catch(e) {}
} else {
return dc(json);
}
};
}();
or, the "safe mode" part should be removed from the docs ?

Condor
11 Aug 2009, 6:57 AM
Almost, according to the docs it should return 'null'.

this.decode = function(){
var dc;
return function(json, safe) {
if(!dc){
dc = isNative() ? JSON.parse : doDecode;
}
if(safe){
try{
return dc(json);
}catch(e){
return null;
}
}
return dc(json);
};
}();

11 Aug 2009, 7:35 AM
So, either the source code of Ext.util.JSON should contain something like


this.decode = function() {
var dc;
return function(json, safeMode) {
if (!dc) {
// setup decoding function on first access
dc = isNative() ? JSON.parse : doDecode;
}
if (safeMode) {
try { // yes, I know this is ugly
return dc(json);
} catch(e) {}
} else {
return dc(json);
}
};
}();
or, the "safe mode" part should be removed from the docs ?

I think it should be added and used by default.

Snaker
11 Dec 2009, 3:10 AM
this code would do it. Is there a better way to override it?


Ext.util.JSON.decode = function() {
var dc;
return function(json, safeMode) {
if (!dc) {
dc = isNative() ? JSON.parse : doDecode;
}
if (safeMode) {
try {
return dc(json);
} catch(e) {}
} else {
return dc(json);
}
}
};
Ext.decode = Ext.util.JSON.decode;

11 Dec 2009, 3:54 AM
your problem is that doDecode is not within scope of the override.

sherpam
7 Apr 2010, 7:38 AM
If you really need it you could override it like this:



(function() {
var oldDc = Ext.util.JSON.decode;
if (oldDc.toString().indexOf("safe") === -1) {
Ext.util.JSON.decode = function(json, safe) {
if (!safe) {
return oldDc(json);
} else {
try{
return oldDc(json);
}catch(e){
return null;
}
}
};
Ext.decode = Ext.util.JSON.decode;
}
}());

Mike Robinson
7 Apr 2010, 8:54 AM
JSON is a "best of times, worst of times" proposition: it works very fast because it is a blind eval() ... which works because JSON is, in fact, "JavaScript code."

The downside is that JSON is completely trusting of the host. Whatever is downloaded from the host (and this, of course, includes "all of the JavaScript that's running on the client anyway...") is implicitly assumed to be trustworthy. (And experienced...)

There really should not be any "syntax errors." Your host is supposed to know what it is doing. Features like "safe mode" simply exist to try to keep the JavaScript from puking-up a piston altogether... the exception that is thrown gets caught and absorbed. So, the JavaScript is able to keep going, more-or-less. (No, actually just "less." The condition is fatal. It's been shot in the gut but it's still walking.)

You really need to know that the host is always going to be able to supply valid JSON. No matter what the user's data contains. And, really, you ought to be able to be confident of that, because well-designed and well-tested host side code abounds.

Tom23
7 Apr 2010, 10:18 AM
Great, if you have full control over the host configuration.

I develop ExtJS applications for customers with huge server infrastructure. I cannot reconfigure the servers. This is how it works:

User gets a session cookie from http://foo.bar/login/
The ExtJS application in http://foo.bar/myapp/ is launched
JSON is recieved from http://foo.bar/myapp/json/
If the session times out, the server redirects to http://foo.bar/login/


Now, the desired behaviour is: if a HTML response is recieved, the app should inform the user: "Your session has timed out. Redirecting to http://foo.bar/login".

So I know for sure that the host either sends valid JSON or valid HTML (These are mutually exclusive...)
How should the app handle this?

aserron
6 May 2010, 11:41 AM
You could extract json from the output if it's present.

Then you wont eval nothing than the json out even if its mixed with server msgs.

also you could trap garbage to log it or something.

By the way json must be valid to avoid js error.