Cursor Chaos After the Emoji — JavaScript Bug Hunt

Inspired by collaborative editors corrupting text around emoji.

  • Language: JavaScript
  • Layer: Frontend
  • Difficulty: Medium
  • Concepts: Unicode, Strings
  • Modelled on: Google Docs
  • Visible tests: plain ASCII inserts normally; inserting after an emoji keeps it intact; inserting between two emoji
  • Reward: 50 XP for a complete fix

Briefing

Inspired by collaborative editors corrupting text around emoji. Positions in the document model are user-perceived characters (code points) — but the insert routine slices at raw UTF-16 offsets, splitting surrogate pairs and producing mojibake.

Fix insertAt.js so inserts land where humans expect.

Bug report

BUG-D0C5 · Priority: High · Reported by: collab-editing

insertAt("a🙂b", 2, "X") must produce "a🙂Xb" — position 2 is after the emoji, which is ONE character to the user.

Observed output contains a lone surrogate: the emoji is torn in half and the document renders �X� from that point on.

Logs

[ot] apply insert pos=2 -> "a\ud83dX\ude42b" (broken surrogate pair)

The code as shipped

src/editor/insertAt.js (editable)

// Inserts a string at a position measured in user-perceived characters.
exports.insertAt = function (text, pos, insertion) {
  return text.slice(0, pos) + insertion + text.slice(pos);
};

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.