Created
July 21, 2018 20:50
-
-
Save lucaong/a7d7a2eee869e2c7afe8b59fc0dfda2b to your computer and use it in GitHub Desktop.
Safari bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Safari bug | |
// ========== | |
// | |
// Two strings, that share a prefix after a regexp normalization, | |
// are used as keys in an object. Then, they are traversed character | |
// by character and recomposed into another string by concatenation, | |
// and each is put in an array. When they are used to index the object, | |
// the second one is not found among the keys: the reason is that it | |
// contains a null byte (copy/paste it into a file and inspect the binary | |
// representation, e.g. with `xxd`, to see that). | |
// | |
// NOTES: | |
// 1. One string, before normalization, has to contain a 2-bytes character | |
// 2. Using the strings as object keys and using concatenation both seem necessary | |
// 3. If the corrupted string is "touched" before being used to index the object, | |
// it "fixes itself". By "touched" I mean that it is logged with console.log, or | |
// used in a comparison, or any String.prototype method is called on it. | |
// 4. Interestingly, if a Object.prototype method is called on the string instead, | |
// the null byte does not get removed, and the bug occurs. | |
var strings = ['xxĀ', 'xxx'].map(str => str.replace(/\W/, '')) | |
var map = {} | |
strings.forEach((string, i) => { | |
map[string] = i | |
}) | |
var prefix = '' | |
var words = [] | |
strings.forEach(string => { | |
for (var i = 0; i < string.length; i++) { | |
if (prefix.length < i + 1) { | |
prefix = prefix + string[i] | |
} | |
} | |
words.push(prefix) | |
}) | |
words.forEach(word => { | |
if (map[word] == null) { | |
alert("This should not happen! String corrupted with null byte: " + word) | |
} else { | |
alert("All fine: " + word) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment