
要注意!サロゲートペア
サロゲートペアって
この記事は ソフトウェアテストの小ネタAdvant Calender 8日目の記事です。
小ネタ前提とのことですので、ピンポイントな記事としています。サロゲートペアよく知ってるし、よくテストしてるよーという方は優しくこっそりスルーしていただければと思います。
私はかつて、マイクロソフトでテストを担当していたことがあり、L18N系のテストとして、文字コード周りのテストは必ず行うべきテストのひとつでした。文字コード周りのテストといってもいろいろありますが、今回は、バグが結構出やすい文字列としての「サロゲートペア」文字について書きます。
(といいながら、復習しながら書いているのは内緒です)
まず、具体例から行きます。
「𠮟る」の太字とした漢字部分。”叱”ではないことに注意 (末尾補足※1)
がサロゲートペアの具体例の一つです。日本人の人名として、サロゲートペアが含まれることは少なからずあり、このあたりの確認が疎かになっているとまじヤバい事態になることは想像に難くないです。
最近の開発は、国際化対応前提で、Shift-JISを用いることは大幅に減り、Unicode対応することがほとんどだと思います。
サロゲートペアについての記事はググったり、ChatGPTに聞いてもいい感じに教えてくれそうではあります。
いきなり具体例から入りましたが、これがサロゲートペアじゃない文字と何が違うのか、目に見える形にしてみたいと思います。
「森鷗外𠮟る」をテキストエディタで入力し、バイナリエディタなどで、16進数で実際に表示させてみるのが、理解を深めるのに有効だとおもいます。今回は、Mac OSX のターミナルで "hexdump"を使った結果を共有してみたいと思います。事前に 「森鷗外𠮟る」 という文字列をテキストエディタで UTF-8形式で 保存した状態で "hexdump -C"コマンドで中身を除いた結果です。呪文みたいなのが、実際のファイルの中身を16進数で表示したものです。何かに気づきませんか?
UTF-8 において、森鷗外は
森[e6 a3 ae]
鷗[e9 b7 97]
外[e5 a4 96]
𠮟[f0 a0 ae 9f] (図の赤枠部分)
る[e3 82 8b]

そうです。バイトの長さが違うのです!
サロゲートペアがヤバいと話題になり始めたことの記事を一つ共有しておきます。
http://bluewatersoft.cocolog-nifty.com/blog/2009/10/windows-7-2-482.html
何がヤバいのか?
最大文字数チェックのすり抜けや、サロゲートペアが含まれた文字列でファイルを保存する際、エラーとならず一見保存したかのように見えて、ファイルを表示できない、編集できない、削除できない。そんなヤバい自体がわりと起こります。笑えない話ですが、テスト用に使っているプロダクトにそのバグが残っていましたが、敢えてサロゲートペアに関連したバグを学ぶいい機会と捉えて敢えて残しているのは内緒です。(内緒ではありません)
(追記)もっとわかりやすい例が欲しいと思って、できるだけ身近な例(文字カウント数がバグってしまうもの)を見つけたのでその例の画像を載せておきます。サロゲートペアの「𠮟」を含んだ「𠮟る」が3文字扱いになっています。

じゃあ、実際にテストする時どうすればいいの
ゼロから原理を学んで、必殺の文字列を考えるのも良いでしょう。今回は小ネタということで、一つ便利なオンラインツールを紹介します。
いろんな文字列を文字数指定して生成してくれる便利ツールです。
https://lazesoftware.com/ja/tool/strgen/
使用イメージ(文字列の種類:サロゲートペア、文字数:99 )

さいごに
いろいろなテストありますが、文字コード周りも、理解を深めておくときっと役立つことがあると思います。少しでも参考になる部分があれば嬉しいです。
Happy Testing to you!!
補足
※1)コードポイント表記をすると、下記のようになります。
叱 は「U+20BAF」(サロゲートペア)
叱 は「U+53F1」(サロゲートペアじゃない方)
Unicodeについての参考記事として下記も載せておきますね。