ਇੱਕ ਚੌੜਾਈ ਦੀ ਜਾਂਚ (Width Check) ਨੇ ਕਿਹਾ ਕਿ ਸਟ੍ਰਿੰਗ ਕੱਟਣ ਲਈ ਸੁਰੱਖਿਅਤ ਸੀ। ਇਸਨੇ ਇੱਕ ਕਾਂਜੀ (Kanji) ਨੂੰ ਅੱਧ ਵਿਚਕਾਰੋਂ ਵੰਡ ਦਿੱਤਾ।

ਇੱਕ ਨਾਮ ਇੱਕ ਟਰਮੀਨਲ ਟੇਬਲ ਵਿੱਚ ਦਰਜ ਕੀਤਾ ਗਿਆ ਅਤੇ ਟੁੱਟਿਆ ਹੋਇਆ ਬਾਹਰ ਆਇਆ। ਉਪਨਾਮ 𠮷田 ਸੀ।

ਪਹਿਲਾ ਅੱਖਰ ਆਮ 吉 ਨਹੀਂ ਹੈ। ਇਹ 𠮷 (U+20BB7) ਹੈ। ਇਹ ਅਸਲੀ ਜਾਪਾਨੀ ਪਰਿਵਾਰਕ ਨਾਮਾਂ ਵਿੱਚ ਵਰਤਿਆ ਜਾਣ ਵਾਲਾ ਇੱਕ ਦੁਰਲੱਭ ਰੂਪ ਹੈ। ਟੇਬਲ ਨੇ ਕਾਲਮ ਵਿੱਚ ਫਿਟ ਹੋਣ ਲਈ ਸੈੱਲ ਨੂੰ ਛੋਟਾ (truncate) ਕਰ ਦਿੱਤਾ। ਇਸ ਨਾਲ ਇੱਕ ਟੁੱਟਿਆ ਹੋਇਆ ਅੱਖਰ ਰਹਿ ਗਿਆ।

ਇਹ ਬੱਗ ਕੋਡ ਦੀ ਇੱਕ ਸਿੰਗਲ ਲਾਈਨ ਵਿੱਚ ਸੀ। ਇਹ ਇੱਕ ਅਪਟੀਮਾਈਜ਼ੇਸ਼ਨ (optimization) ਸੀ ਜਿਸ ਨੇ ਫੈਸਲਾ ਕੀਤਾ ਕਿ ਸਟ੍ਰਿੰਗ ਨੂੰ ਇੰਡੈਕਸ (index) ਰਾਹੀਂ ਕੱਟਣਾ ਸੁਰੱਖਿਅਤ ਹੈ।

ਇੱਕ JavaScript ਸਟ੍ਰਿੰਗ ਦੀਆਂ ਤਿੰਨ ਵੱਖ-ਵੱਖ ਲੰਬਾਈਆਂ ਹੁੰਦੀਆਂ ਹਨ: • ਕੋਡ ਯੂਨਿਟਸ (Code units) (.length): "𠮷".length 2 ਹੈ। • ਕੋਡ ਪੁਆਇੰਟਸ (Code points): [..."𠮷"].length 1 ਹੈ। • ਡਿਸਪਲੇਅ ਵਿਡਥ (Display width): 𠮷 2 ਕਾਲਮ ਘੇਰਦਾ ਹੈ।

ਮਿਆਰੀ ਅੰਗਰੇਜ਼ੀ ਟੈਕਸਟ ਲਈ, ਇਹ ਸਾਰੇ ਅੰਕ ਇੱਕੋ ਜਿਹੇ ਹੁੰਦੇ ਹਨ। ਇਹ ਇਤਫ਼ਾਕ ਕੋਡ ਨੂੰ ਸੁਰੱਖਿਅਤ ਦਿਖਾਉਂਦਾ ਹੈ।

ਅੱਖਰ 𠮷 ਇਸ ਨਿਯਮ ਨੂੰ ਤੋੜਦਾ ਹੈ। ਇਸਦੇ 2 ਕੋਡ ਯੂਨਿਟਸ ਹਨ ਕਿਉਂਕਿ ਇਹ ਇੱਕ ਸਰੋਗੇਟ ਪੇਅਰ (surrogate pair) ਹੈ। ਇਸਦੇ 2 ਕਾਲਮ ਹਨ ਕਿਉਂਕਿ ਇਹ ਇੱਕ ਚੌੜਾ (wide) ਅੱਖਰ ਹੈ। ਅੰਕ ਮਿਲਦੇ ਹਨ (2 = 2), ਪਰ ਵੱਖ-ਵੱਖ ਕਾਰਨਾਂ ਕਰਕੇ।

ਲਾਇਬ੍ਰੇਰੀ cli-table3 ਨੇ ਇੱਕ ਫਾਸਟ ਪਾਥ (fast path) ਦੀ ਵਰਤੋਂ ਕੀਤੀ: ਜੇਕਰ ਕੋਡ ਯੂਨਿਟ ਲੰਬਾਈ ਡਿਸਪਲੇਅ ਵਿਡਥ ਦੇ ਬਰਾਬਰ ਹੈ, ਤਾਂ ਸਟ੍ਰਿੰਗ ਨੂੰ ਇੰਡੈਕਸ ਰਾਹੀਂ ਕੱਟੋ।

ਇਹ ਸਾਲਾਂ ਤੱਕ ਕੰਮ ਕਰਦਾ ਰਿਹਾ ਕਿਉਂਕਿ 漢 ਵਰਗੇ ਆਮ ਜਾਪਾਨੀ ਅੱਖਰਾਂ ਦੀ ਲੰਬਾਈ 1 ਅਤੇ ਚੌੜਾਈ 2 ਹੁੰਦੀ ਹੈ। ਉਹ ਕਦੇ ਵੀ ਫਾਸਟ ਪਾਥ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚਦੇ।

ਫਾਸਟ ਪਾਥ ਸਿਰਫ਼ 𠮷 ਜਾਂ ਇਮੋਜੀ (emojis) ਵਰਗੇ ਦੁਰਲੱਭ ਅੱਖਰਾਂ ਲਈ ਹੀ ਚਾਲੂ ਹੁੰਦਾ ਹੈ। ਇਹਨਾਂ ਅੱਖਰਾਂ ਦੀ ਲੰਬਾਈ 2 ਅਤੇ ਚੌੜਾਈ 2 ਹੁੰਦੀ ਹੈ। ਕੋਡ ਸੋਚਦਾ ਹੈ ਕਿ ਉਹ ਸਧਾਰਨ ਇੱਕ-ਯੂਨਿਟ ਵਾਲੇ ਅੱਖਰ ਹਨ। ਇਹ ਉਹਨਾਂ ਨੂੰ ਇੰਡੈਕਸ ਰਾਹੀਂ ਅੱਧ ਵਿਚਕਾਰੋਂ ਕੱਟ ਦਿੰਦਾ ਹੈ। ਇਸ ਨਾਲ ਇੱਕ ਇਕੱਲਾ ਸਰੋਗੇਟ (surrogate) ਪਿੱਛੇ ਰਹਿ ਜਾਂਦਾ ਹੈ। ਇਹੀ ਕਾਰਨ ਹੈ ਕਿ ਟਰਮੀਨਲ ਵਿੱਚ ਇੱਕ ਟੁੱਟਿਆ ਹੋਇਆ ਡੱਬਾ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।

ਇਸ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ:

  • ਸਰੋਗੇਟ ਪੇਅਰਾਂ ਨੂੰ ਬਾਹਰ ਰੱਖਣ ਲਈ ਫਾਸਟ ਪਾਥ ਦੀ ਰੱਖਿਆ (guard) ਕਰੋ।
  • ਕੋਡ ਯੂਨਿਟਸ ਦੀ ਬਜਾਏ ਕੋਡ ਪੁਆਇੰਟਸ ਰਾਹੀਂ ਟ੍ਰਿਮ (trim) ਕਰੋ।

Array.from(str) ਦੀ ਵਰਤੋਂ ਕਰਨ ਨਾਲ ਮਦਦ ਮਿਲਦੀ ਹੈ ਕਿਉਂਕਿ ਇਹ ਕੋਡ ਪੁਆਇੰਟ ਰਾਹੀਂ ਇਟਰੇਟ (iterate) ਕਰਦਾ ਹੈ। ਇਹ ਯਕੀਨੀ ਬਣਾਉਂਦਾ ਹੈ ਕਿ ਤੁਸੀਂ ਕਦੇ ਵੀ ਕਿਸੇ ਅੱਖਰ ਨੂੰ ਅੱਧ ਵਿਚਕਾਰੋਂ ਨਹੀਂ ਕੱਟੋਗੇ।

ਸਬਕ ਸਧਾਰਨ ਹੈ: ਕਦੇ ਵੀ ਇੱਕ ਯੂਨਿਟ ਨਾਲ ਮਾਪੋ ਨਾ ਅਤੇ ਦੂਜੇ ਨਾਲ ਕੱਟੋ ਨਾ। ਜੇਕਰ ਤੁਸੀਂ ਡਿਸਪਲੇਅ ਵਿਡਥ ਜਾਂ ਕੋਡ ਪੁਆਇੰਟਸ ਨੂੰ ਮਾਪਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਉਹਨਾਂ ਹੀ ਯੂਨਿਟਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਕੱਟਣਾ ਚਾਹੀਦਾ ਹੈ।

ਆਪਣੇ ਕੋਡ ਦਾ ਟੈਸਟ CJK Extension B ਅੱਖਰ ਜਾਂ ਇਮੋਜੀ ਨਾਲ ਕਰੋ। ASCII ਕਦੇ ਵੀ ਇਸ ਬੱਗ ਨੂੰ ਪ੍ਰਗਟ ਨਹੀਂ ਕਰੇਗਾ।

ਸਰੋਤ: https://dev.to/greymothjp/a-width-check-said-the-string-was-safe-to-cut-it-split-a-kanji-in-half-4hjk

ਵਿਕਲਪਿਕ ਸਿੱਖਣ ਭਾਈਚਾਰਾ: https://greymoth-jp.github.io/cjk-failure-corpus/