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

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

もずはっく日記(2013年1月)

2013年1月2日

Bug-org 823369 mozilla::widget::EventFlags assumes its size is less than uint32_t 初回投稿日時: 2013年01月02日09時42分11秒
カテゴリ: Mozilla Core Mozilla20 バグ修正
固定リンク: id=2013010200
SNS: (list)

EventFlagsboolのbit fieldとして作成しましたが、速度やメンテナンス製を考慮して、内部ではuint32_tとしてmemcpy()を利用したりしています。メンバが増えていくと、そのうちにuint32_tではサイズが足りなくなる可能性があり、問題になる可能性があります。

えむけいさんに教えて頂いた、MOZ_SATATIC_ASSERT()でビルド時にサイズ確認を行うようにし、typedef uint32_t EventFlags::RawFlagsと定義することで、サイズ変更の際には1行変更するだけでメンテナンスできるように修正しています。

Bug-org 822866 Can't build using MSVC with enable-optimize=-O2 since landing of bug 813445 初回投稿日時: 2013年01月02日10時03分08秒
最終更新日時: 2013年01月02日10時04分13秒
カテゴリ: Mozilla Core Mozilla20 Windows バグ修正
固定リンク: id=2013010201
SNS: (list)

Bug-org 813445の修正で、VC++では-O2で最適化ビルドを作ろうとするとコンパイラがクラッシュするというregressionが出ました。もちろんVC++自体のバグなのですが、そうも言ってられません。

パフォーマンスを意識して、メンバを一括でmemcpy()を使ってOR演算や、初期化できるようにしていましたが、コンストラクタや、代入演算子を定義していたため、C++03では、非PODクラスということになるらしく、memcpy()が危険だという助言を、例によってえむけいさんから頂きました。ところが、PODクラスにしてもVC++のクラッシュは修正できませんでした。

そこで、クラッシュした行に着目してみると、以下のようなコードになっていました。

inline EventFlags operator|(const EventFlags& aOther) const
{
  EventFlags flags;
  flags.SetRawFlags(GetRawFlags() | aOther.GetRawFlags());
  return flags;
}

クラッシュしたのは、SetRawFlagsの行です。ここで、それぞれのメソッドの実装は次のようになっています。

inline void SetRawFlags(RawFlags aRawFlags)
{
  MOZ_STATIC_ASSERT(sizeof(EventFlags) <= sizeof(RawFlags),
    "mozilla::widget::EventFlags must not be bigger than the RawFlags");
  memcpy(this, &aRawFlags, sizeof(EventFlags));
}
inline RawFlags GetRawFlags() const
{
  RawFlags result = 0;
  memcpy(&result, this, sizeof(EventFlags));
  return result;
}

試しに、これらのinline指定を削除してみると、コンパイラがクラッシュしなくなりました。ということで、バグはここの最適化にあるようです。

結果的には、operatorUnion()というメソッドに変更し、一度、変数にGetRawFlags()から得た演算結果を保存してから、SetRawFlags()を呼び出すことで、コンパイラのバグを回避しています。

また、非PODクラスのままでは不安が残るので、EventFlagsBaseEventFlagsと名前を変更し、コンストラクタを削除、上述の通り、|=演算子をUnion()というメソッドに置き換えました。

そして、コンストラクタが無いのは不便なので、新たにEventFlagsというコンストラクタだけを追加した派生クラスを用意し、Union()メソッドを使うような局面では、こちらをローカル変数として利用することで、Clear()メソッドをいちいち呼ばなくとも、自動で初期化されるように修正しています。

Bug-org 815383 pressing command key over vnc results in "Assertion failure: !(flag & [aNativeEvent modifierFlags]), at .../widget/cocoa/TextInputHandler.mm:1676" 初回投稿日時: 2013年01月02日10時17分13秒
最終更新日時: 2013年01月02日10時17分35秒
カテゴリ: Mac Mozilla Core Mozilla19 Mozilla20 バグ修正 バグ却下
固定リンク: id=2013010202
SNS: (list)

Bug-org 786956の修正の後、VNC経由でMacでデバッグビルド上でモディファイアキーを押すと、MOZ_ASSERT()にひっかかってクラッシュするというバグです。

調べてみると、MacのVNCサーバはOSSではなく、Apple謹製の様ですが、そのVNCサーバの生成するFlagsChangedイベントが変なために、新しいコードではうまく処理できなくなっていました。

まず、それなりにリスキーな変更が必要なため、19からはBug-org 786956の修正の修正はバックアウトしています。

続いて、キーコードが適切に設定されていないFlagsChangedイベントであっても、keydownイベントも処理されるように修正しました。

ただし、VNCの送信するイベントの仕様上、右 shiftキー、右 controlキー、右 optionキー、右 commandキーを押しても、KeyboardEvent.locationは常に、KeyboardEvent.DOM_KEY_LOCATION_LEFTが返されます。このバグが気に入らない方はAppleに報告をお願いします。

Bug-org 812143 Union solid text underline rect with overflow rect even if the style is none 初回投稿日時: 2013年01月02日10時27分31秒
カテゴリ: CSS Mozilla Core Mozilla20 バグ修正
固定リンク: id=2013010203
SNS: (list)

-moz-text-decoration-style: -moz-none;と、それ以外のスタイルを動的に変更すると、再描画領域が適切に計算されないことがある、というバグです。

:hoverで下線を追加するサイトのパフォーマンスのために、常に下線の領域はoverflow領域に含めて計算しているのですが、-moz-noneの場合に、これを含めていませんでした。-moz-none自体、IMEの内部処理のための独自の値なのでWebサイトで利用されることは無いとは思いますが、念のため、-moz-noneが指定されている場合には、solidと読み替えて、overflow領域を計算するように修正しています。

Bug-org 825167 [TSF] "ASSERTION: nsTDependentString must wrap only null-terminated strings: 'mData[mLength] == 0'" when composition string becomes 0 length 初回投稿日時: 2013年01月02日10時34分04秒
カテゴリ: Mozilla Core Mozilla20 TSF Windows バグ修正
固定リンク: id=2013010204
SNS: (list)

ITextStore::SetText()や、ITextStore::InsertTextAtSelection()で指定されたUnicode文字列を取り扱う際に、nsDependentStringに、長さを指定して利用していたのですが、この警告がATOK利用時に発生していることに気付きました。

長さを指定できるnsDependentStringで、終端にヌル文字が無いといけない、というのも変な感じがするのですが、そういった利用を想定しているのは、nsDependentSubstringの様ですので、そちらを利用するように修正しています。

詳しいことはcomment 4に情報を頂いてますので、参照してください。

Bug-org 672193 Improve WM_APPCOMMAND support ("Close" Multimedia Key on Windows closes browser, not current tab) 初回投稿日時: 2013年01月02日10時58分50秒
最終更新日時: 2013年01月02日11時03分10秒
カテゴリ: Firefox Mozilla Core Mozilla20 SeaMonkey Thunderbird Windows バグ修正
固定リンク: id=2013010205
SNS: (list)

MicrosoftのWireless Keyboard 3000 v2.0のような、マルチメディアキーがついたキーボードで、新規作成キーや、閉じるキーを押した時に、他のブラウザではタブが作成されたり、タブが閉じられたりするのですが、FirefoxではWM_APPCOMMANDのこれらのコマンドに対応していないため、キーボードユーティリティが、Ctrl+N等のよく知られたショートカットキーのイベントを生成するため、タブの代わりにウインドウが開いたり、閉じたりするというバグです。

WindowsのnsWindow側では、以下の様に、DOMCommandEventを生成するようにしました。

新たに対応したDOMCommandEventcommand属性値と、APPCOMMAND_*値、Firefoxの機能との対応表
command属性値APPCOMMAND_*対応するFirefoxの機能
CloseAPPCOMMAND_CLOSEタブを閉じる
FindAPPCOMMAND_FIND検索
HelpAPPCOMMAND_HELPヘルプ
NewAPPCOMMAND_NEW新しいタブ
OpenAPPCOMMAND_OPENファイルを開く...
PrintAPPCOMMAND_PRINT印刷...
SaveAPPCOMMAND_SAVE名前を付けてページを保存...
ForwardMailAPPCOMMAND_FORWARD_MAIL対応機能無し
ReplyToMailAPPCOMMAND_REPLY_TO_MAIL対応機能無し
SendMailAPPCOMMAND_SEND_MAILページの URL をメールで送信...

Thunderbirdや、SeaMonkeyでもハンドラだけ書けばこれらに対応できます。SeaMonkeyのバグは既に登録されています。パッチ書く人募集中です。

2013年1月10日

Bug-org 819252 CMD + swipe left to open previous location in new tab is broken with Magic Mouse 初回投稿日時: 2013年01月10日11時41分42秒
カテゴリ: Firefox Mac Mozilla20 バグ修正
固定リンク: id=2013011000
SNS: (list)

Bug-org 814303の修正で、Macでも、command+ホイールでズームができるようになりましたが、これにより、commandキーが押されている時に、常にスワイプイベントが生成されなくなってしまいました。そのため、commandキーを押しながら左右にスワイプすることで、新しいタブで「戻り」先のページや、「次」のページを開くことができなくなっていました。

Bug-org 786120の修正のおかげで、水平方向のみ、ズーム機能を殺すことが可能になってますので、そのように修正して対応しています。

Bug-org 823904 Support some appcommands which can be implemented with content command events 初回投稿日時: 2013年01月10日11時54分55秒
カテゴリ: Mozilla Core Mozilla21 Windows バグ修正
固定リンク: id=2013011001
SNS: (list)

WM_APPCOMMANDの、APPCOMMAND_COPYAPPCOMMAND_CUTAPPCOMMAND_PASTEAPPCOMMAND_REDOAPPCOMMAND_UNDOにはBug 1908の修正で作成した、nsContentCommandイベントを利用することで、Geckoのレベルで、マルチメディアキーボードのコピー切り取り貼り付け元に戻すやり直しキーに対応しました。

残念ながら、ギリギリでFirefox 20には間に合いませんでした。ただ、最近のキーボードでは元に戻すやり直しキーをMicrosoftのWireless Keyboard 3000 v2.0ぐらいでしか確認できませんでしたので、これらのキーが流行った頃のキーボードを使い続けている方にしかメリットはないかと思います(それでもたぶん、キーボードのユーティリティでCtrl+C等、一般的なショートカットキーのメッセージを送信することで対応してると思いますが)。

2013年1月23日

Bug-org 825924 Form autocomplete does not properly reset 初回投稿日時: 2013年01月23日17時16分39秒
カテゴリ: Events Firefox Mozilla Core Mozilla21 バグ修正
固定リンク: id=2013012300
SNS: (list)

<input>等に何文字か入力し、オートコンプリートの候補が絞られた後で、入力内容を全て選択し、コンテキストメニューからそれを切り取った後、再度入力を開始しても、候補が絞り込まれたままになっている、というバグです。Aliceさんのおかげで、regressionの原因がBug-org 668606の修正にあることが分かりました。

Bug-org 668606の修正では、エディタの種類に関係無く、inputイベントを発生させるために、nsEditorが内容の変更があった際にイベントを発生させるように修正しました。この際に、エディタのインターフェースから属性を一つ削除してシンプルにできる様になったのですが、この修正にミスがありました。

削除された属性は、inputイベントをtrustedイベントとして生成するかどうかに関わるもので、セキュリティのために、イベントや、コマンドのハンドリングを開始した際にスタックに、HandlingTrustedActionクラスのインスタンスを生成し、これが、nsEditorに、trustedなinputイベントを生成すべきかどうかを設定していました。この、クラスの生成に漏れがあった、というのがこのバグの直接の原因です。

しかし、別件でD3Eの仕様を読んでいる時に気になっていたのですが、例え、untrustedなイベントが原因でエディタに変更があったとしても、それは、trustedなinputイベントを常に生成すべきなのではないか、逆に言うと、document.createEvent()で生成しない限り、untrustedなイベントにはなるべきではないのではないかという疑問がありました。

この機会にそれをSmaugに確認してみたところ、やはり、nsEditorは常にtrustedなinputイベントを生成するべきだという意見でしたので、HandlingTrustedActionクラスを廃止し、常に、trustedなinputイベントを生成するように修正しました。

これにより、このバグが再現しないようになっています。

既に、Bug-org 698949の修正により、untrustedなキーイベントでエディタの内容が変更されて、オートコンプリート履歴をWebページのスクリプトで読まれてしまうバグは完全消滅していますので、この修正による、セキュリティ的な問題は既に無いと考えています。

ただし、inputイベントisTrusted属性を監視しているWebアプリでは、なんらかの挙動の変化が発生する可能性があるので注意してください。

Bug-org 821329 Input widgets don't accept character input with MacOS's build-in handwriting feature 初回投稿日時: 2013年01月23日17時28分35秒
カテゴリ: Events Firefox Mac Mozilla Core Mozilla19 Mozilla20 Mozilla21 Thunderbird バグ修正
固定リンク: id=2013012301
SNS: (list)

Macのタッチパッド上で指で漢字を直接書いて、入力する機能が、Firefox 17以降で動作しなくなってしまっているというバグです。同様の症状として、日本語IMEの文字入力パレットからも入力できなくなっているという情報(苦情とも言う)をもらっています。

Bug-org 775414の修正でキーイベントの初期化まわりを書き直した際に、ネイティブキーイベントを伴わずに一文字だけ入力される場合のコードで、charCode属性値を設定し忘れていたのが原因でした。

修正リスクがほとんど皆無な上に、影響が大きいので、ESR17も含め、全てのブランチにパッチを投入しましたので、Firefox、Thunderbird共に、次のアップデートでは修正されます。

2013年1月31日

Bug-org 832120 Shouldn't the default cursor of editable element be also I-beam? 初回投稿日時: 2013年01月31日18時01分51秒
カテゴリ: CSS Mozilla Core Mozilla21 バグ修正
固定リンク: id=2013013100
SNS: (list)

twitter.comのエディタ上にマウスカーソルを移動した際に、カーソルの下にテキストがない場合は、Iビームカーソルではなく、デフォルトのカーソルで表示されてしまう、というバグです。

twitter.comは最近、エディタに<textarea>要素を使うことをやめ、<div contenteditable>を代わりに使うようになっています。

全てのブラウザは、contentediableな要素の上でも、デフォルトのスタイルシートでは、cursor: auto;となっていて、あとはブラウザ自身の判断でカーソルを変更することになります。

Geckoでは、編集可能かどうかにかかわらず、<input>要素や、<textarea>要素のような、フォームコントロール要素以外ではテキストがある場合にはIビームを、それ以外の場合はデフォルトのカーソルを利用するようにしていましたが、他のブラウザにあわせ、編集可能な要素の上では(ほぼ)常にIビームにするように修正しました。

これで、twitter.comのように、<textarea>のように見える、リッチテキストエディタが埋め込まれている場合に、違和感を感じなくなっているかと思います。