Are there any characters that are not allowed in localStorage?
Asked Answered
S

2

5

I've been using localStorage to store some binary data in string format, and although the value is definitely set (alerting it immediately after setting, or even some time after setting, shows the correct value) it is lost when the page next loads.

At first I figured it might be because the data contained null bytes, so I redesigned the compressor so that it would never output them. However, this made no difference as the value is still lost.

I added localStorage.testing = 1 immediately after setting the binary data. This value is kept, even when the other is lost.

I am absolutely certain there is no code to delete localStorage.myitem.

What could be causing this issue?

If it helps any, here is the data I'm trying to store, in hex:

0x1103c0a0   0xd6cf0305   0xc0a0d6cf   0x0307c0a0   0xd6cf0309   0xc0a0d6cf
0x030bc0a0   0xd6cf030d   0xc0a0d6cf   0x0311c0a0   0xd6cf0313   0xc0a0d6cf   0x0301

EDIT: I just tested with localStorage.testvalue = realvalue.replace(/[\x00-\x1f]/g,''); and that successfully saved it. So, I'd like to know where the specification says that control characters may not be used in strings.

Shantelleshantha answered 23/6, 2012 at 15:31 Comment(0)
U
14

I've set up a test case, and ran the test in various browsers. The results are below (the inclusive ranges of character codes are mentioned). Tests started at the minimum browser version which support localStorage.

  • Chrome 5 - 20: 0x0000 - 0xFFFF
  • Opera 10.50 - 12.00: 0x0000 - 0xFFFF
  • Safari 4.0 - 5.1.7: 0x0000 - 0xFFFF
  • Firefox 3.5 - 16alpha: 0x0000 - 0xD7FF and 0xE000 - 0xFFFE (0xD800-0xDFFF and 0xFFFF are turned in two characters after LS)
  • IE8, IE9, IE10PP6: 0x0009, 0x000A, 0x000D, 0x0020 - 0xD7FF and 0xE000 - 0xFFFD. (Other ranges are either ignored or cause an "Invalid argument" error).
    0x0000 is a NULL-byte, which truncates all following characters in IE.

So, the character ranges 0x20 - 0xD7FF and 0xE000 - 0xFFFD plus 0x09, 0x0A and 0x0D are safe.


I've created three test cases:

  1. The quickest test case, which creates a string with all characters, and tests the value after setting localStorage
  2. A method which used the SPACE character (0x20) as a delimiter, to properly deal with browsers which create a character with length 2.
  3. The worst method, because IE throws an error for invalid strings. Each character is tested individually, which is quite expensive.

All test functions are available in JSFiddle, the first test case is visible below:

function run_test(lowerlimit, UPPERLIMIT) {
    try {
        if (!window.localStorage) {
            // I recall that in one of the older Chrome version (4),
            // localStorage === null
            return 'Localstorage is not supported';
        }
        if (isNaN(lowerlimit) || isNaN(UPPERLIMIT) || lowerlimit > UPPERLIMIT) {
            return 'One of the limits is not a valid number!';
        }
        var i = lowerlimit - 1;
        var character_range = [];
        while (++i < UPPERLIMIT) character_range.push(i);
        input = String.fromCharCode.apply(String, character_range);
        localStorage.setItem('chartest', input);
        output = localStorage.getItem('chartest');
        if (input === output) {
            return true;
        }
        // Uh oh, not equal!
        var result = [];
        for (i=0; i<UPPERLIMIT-lowerlimit; i++) {
            if (input[i] !== output[i]) {
                result.push(i + lowerlimit);
            }
        }
        return result;
    }catch(e){return 'Error:' + e;}
}
Unduly answered 23/6, 2012 at 23:0 Comment(0)
S
0

After further testing, it appears that when localStorage says it stores strings, what it really means is that it stores string that match:

/^[\x00\x09\x0A\x0D\x20-\xff]*$/

So nothing before space is allowed, except HT, CR, LF and NUL.

That said, still no idea why.

Shantelleshantha answered 23/6, 2012 at 15:45 Comment(3)
Is that testing against multiple browsers, or just one?Thalassic
You've probably tested this in IE only, because I've created and tested the feature in other browsers as well, which show different results (see the other answer).Unduly
Javascript uses UTF-16. Your regex is limited to ASCII.Eleonoraeleonore

© 2022 - 2024 — McMap. All rights reserved.