Firefox pref destroys JSON

I have the following JSON: http://pastebin.com/Sh20StJY

SO removed characters in my post, so look at the link for real JSON

which was generated with JSON.stringify

and saved in Firefox prefs ( pref.setCharPref(prefName, value);

)

The problem is that when I store the value, Firefox does something that corrupts the JSON. If I try JSON.parse

to extract the value from the configuration, I get an error:

Error: JSON.parse: bad control character in string literal

      

If I try to validate the above JSON (which was obtained from settings), I get an error in line 20

, the token value contains two invalid characters.

If I try to execute JSON.parse

right after JSON.stringify

, no error occurs.

Do I need to save something in a different encoding? How can I fix this?

+3


source to share


5 answers


nsIPrefBranch.getCharPref()

only works for ASCII data, however JSON data contains some non-ASCII characters. You can store Unicode data in preferences, it's a little more complicated:

var str = Components.classes["@mozilla.org/supports-string;1"]
                    .createInstance(Components.interfaces.nsISupportsString);
str.data = value;
pref.setComplexValue(prefName, Components.interfaces.nsISupportsString, str);

      

And to read this preference:



var str = pref.getComplexValue(prefName, Components.interfaces.nsISupportsString);
var value = str.data;

      

For reference: Documentation

+4


source


Your JSON appears to contain non-ASCII characters such as ½

. Can you check what encoding everything is processed in?



nsIPrefBranch.setCharPref()

assumes that its input is UTF-8 encoded and the return value is nsIPrefBranch.getCharPref()

always a UTF-8 string. If your input is a byte or character in some other encoding, then you either need to switch to UTF-8 or encode and decode it yourself when interacting with preferences.

+1


source


I did this in one place to fix this issue:

(function overrideJsonParse() {
    if (!window.JSON || !window.JSON.parse) { 
        window.setTimeout(overrideJsonParse, 1); 
        return;  //this code has executed before JSON2.js, try again in a moment
    }
    var oldParse = window.JSON.parse;
    window.JSON.parse = function (s) {
        var b = "", i, l = s.length, c;
        for (i = 0; i < l; ++i) {
            c = s[i];
            if (c.charCodeAt(0) >= 32) { b += c; }
        }
        return oldParse(b);
    };
}());

      

This works in IE8 (using json2 or whatever), IE9, Firefox and Chrome.

+1


source


The code seems to be correct. Try using single quotes "..": "..." instead of double quotes "..": "...".

0


source


I still couldn't find a solution, but I found a workaround:

var b = "";
[].forEach.call("{ JSON STRING }", function(c, i) {
    if (c.charCodeAt(0) >= 32)
        b += c;
});

      

Now b

is new JSON and can work ...

0


source







All Articles