LearnBoost/socket.io — Issue #699: Unicode issue with iOS Emoji
Author: faeldt
Created: 2011-12-26 00:08:04+00:00
State: open

I get this when user send the included emojis from their iPhones.

The server reports this:

[2011-12-22 11:00:36.349] [INFO] console - debug - 'websocket received data packet' '5:2+::{"name":"profile","args":[{"name":"user123","id":"4ef1bde3d3c2b537ccd96f76","presentation":["'

Note the broken JSON.

If I do like this:
presentation[0] = unescape(encodeURIComponent(presentation[0])); etc and then revert back server side things work fine.

I don't feel I do anything weird client side in particular, this is my original code:

presentation.push(x$("#presentation")[0].value); which is just adding the input from a text field. If this text field contains an iphone emoji (testing on iOS 5) things go wrong.

If escaping as shown above things instead looks like this:
ð (and a small three (3) in the corner which i cant seem to parse here).

I am no expert in Unicode or iOS emoji implementations so maybe I am doing something wrong or maybe the above steps with encoding and escaping are actually necessary for this to work. I'd be grateful for some advice.

To sum things up:

For some further classification, I do like this client-side (field used below is 'name', above is 'presentation', which is not irrelevant in this case):

var obj = {};
obj.name = unescape(encodeURIComponent(obj.name));
socket.emit("profile", obj)

And my console log shows this:

{"name":"profile","args":[{"name":"ð(LITTLE-3-IN-THE-CORNER)" etc

If not using iOS emojis the whole unescape(encodeURIComponent( part becomes redundant.

I am using node 0.6.6 and socket.io 0.8.7, which at the time of writing are the latest stable releases of both.

My temporary fix is to clean input from said emoji by using .replace(/[\uD800-\uDB7F\uDB80-\uDBFF\uDC00-\uDFFF\uE000-\uF8FF]+/g, "").