この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2014年7月)

2014年7月24日

Bug-org 1037346 Unexpected assertion in nsTextStore at running toolkit/content/tests/chrome/test_dialogfocus.xul
初回投稿日時: 2014年07月24日06時04分39秒
カテゴリ: Mozilla Core Mozilla33 TSF Windows バグ修正
SNS: (list)

TSFモードを有効にして、全テストを走らせてみると、toolkit/content/tests/chrome/test_dialogfocus.xulを実行中に、nsTextStoreがassertionを吐き、オレンジになるというバグです。

問題のテストはダイアログを開き、初期フォーカスが想定通りの要素になっているのかを検査していました。しかし、このテストの奇妙なところは、windowfocusイベントをcaptureフェイズで捕まえ、そのターゲットを調べ、さらに、そのままダイアログを閉じてしまう、という、現実ではちょっとあり得ないものでした。

IMEStateManagerのログで調べてみたところ、ダイアログの<input>要素にフォーカスが移動した時点で、IMEStateManagerが、IMEの状態を有効にしにいくのですが、この際に、まだ、フォーカスを持っている要素をグローバル変数に格納していませんでした。そして、そのまま、IMEStateManager::UpdateIMEState()が呼び出され、あり得ないフォーカス状態を元にIMEContentObserverが作られ、nsTextStoreがフォーカスを取得した処理を行っていました。その後、IMEStateManager::UpdateIMEState()が終了し、元のフォーカスの移動時の処理に戻ってきた後、<input>要素のエディタがフォーカスイベントを受け取った際に、本来なら存在しない、IMEContentObserverを正しい情報と共に再生成し、nsTextStoreが再び、フォーカスを取得したという通知を受け取って、assertionを吐いていた、という状態でした。

問題は何故、予期しないタイミングでIMEStateManager::UpdateIMEState()が呼び出されていたか、ということなのですが、要素が期待するIMEの状態を、nsIContent::GetDesiredIMEState()で取得しにいくと、その段階で、<input>要素がエディタをようやく作成し、エディタの初期化処理が、IMEStateManager::UpdateIMEState()を呼び出していたため、このような変なスタックになっていたわけです(エディタを後から作るのは、<input>要素が大量にあるサイトでも、初期化のパフォーマンスが低下しないようにするために、初めて必要になった時、例えば、フォーカスを受け取った時にエディタを生成するようになっています)。

IMEStateManager::UpdateIMEState()が呼び出された時点で、グローバル変数が期待通りの状態になっていれば大丈夫かと思いましたが、他のテストがやたらとオレンジになってしまうのでこのアプローチは断念し、ちょっとダサいですが、nsIContent::GetDesiredIMEState()を呼んでいる最中は、IMEStateManager::UpdateIMEState()が呼び出されても何もしない、という形で修正しています。

関連するかもしれないエントリ

bug-org 1037346を含むエントリ