IE5.5以上またはOE5以上を簡単にクラッシュさせる新種のブラクラが報告されました。画像を表示しようとするだけでフリーズするので、通常のセキュリティレベルの設定では、ふせげません(画像を非表示にすればふせげます)。
この問題は、最新のIE/OEが、XBM画像を表示できることに関係しています。XBM(X Bitmap)画像はテキスト形式で、次のようなヘッダを持っています。
#define 画像名_width 画像の幅 #define 画像名_height 画像の高さ
IE/OEは、このヘッダを「すなお」に解釈して指定の高さと幅のビットマップを生成すべくメモリを確保します。悪意、または、おちゃめで、とんでもない数値(例: 100億ピクセル×100億ピクセル)を書くと、IEはメモリの確保に失敗しクラッシュします。詳細については、以下を参照。
次にあげるのは、ごく小さな(2KB)、正常なXBM画像の例で、IE5.5以上のほか、Netscape 4.7x や Opera 6.x でも表示可能です。(Mozilla では表示できないもよう)
この画像の「ソース」は次のようなテキストです。
#define unyu_width 48
#define unyu_height 48
static unsigned char unyu_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0D, 0x00, 0x00, 0x18, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x40, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x81, 0x00, 0xFE, 0x03, 0x80, 0x81, 0x9F, 0x00, 0x3C, 0x00, 0xE0, 0x00, 0x1E, 0x01, 0x18, 0x00, 0x7C, 0x00, 0x00, 0x01, 0x30, 0x00, 0x08, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0x02, 0x60, 0x00, 0xE0, 0x00, 0x1E, 0x02, 0x70, 0x00, 0x60, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0xC6, 0x06, 0x08, 0x78, 0x00, 0x60, 0xFE, 0x03, 0x08, 0x78, 0x00, 0x00, 0x1C, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7E, 0x00, 0x06, 0x3C, 0x00, 0x20, 0x7E, 0x00, 0x7C, 0xE6, 0x03, 0x20, 0xFE, 0x00, 0xE2, 0x03, 0x06, 0x20, 0xFE, 0x00, 0x06, 0x00, 0x04, 0x60, 0xFE, 0x00, 0x3C, 0x00, 0x04, 0x60, 0xFE, 0x01, 0xF0, 0x03, 0x04, 0x40, 0xFE, 0x01, 0xC0, 0x03, 0x04, 0x40, 0xFE, 0x03, 0x00, 0x07, 0x02, 0x40, 0xFE, 0x07, 0x00, 0xFE, 0x01, 0x40, 0xFE, 0x07, 0x00, 0x7C, 0x00, 0x40
};
アパッチはデフォルトで Content-Type: image/x-xbitmap として、.xbmファイルをサポートしています。
類似の現象は、Mozilla が SVG 形式の画像を解釈しようとした場合にも発生する可能性があるように思います。
2002-05-04 アドビと「あーっ、勝手にまねしたなー」と互いに非生産的な訴訟を起こしあっているマクロメディアですが(ユーザが払ったソフト代金は高額の訴訟費用にばけ)、Windows版IE用の Macromedia Flash Player に重大なセキュリティーホールが発覚しました。デフォルトの設定の場合、リモートからブラウザ経由で任意のコードを実行できる、という致命的なものです。詳細は、バグトラックをごらんください。リンク先に書いてあるように、すでにバグフィックスされた最新版が出ています。
不具合が見つかったのは、フラッシュプレーヤーをウェブページにうめこむのに使う flash.ocx(アクティブXコントロール)というフラッシュのコンポーネント。それの古いバージョンがバッファオーバーフローを起こすと報告されています。ファイルバージョンを確認するには、システムフォルダーの Macromed¥Flash あたりを見てください。現在の最新版6.0.29.0以降ならば問題ないです。日本語版もすでにリリースされています。最新版をダウンロードするには、ダウンロードセンター(日本語版)をおとずれてください。そのさい、IEの設定でActiveX関係が有効になっている必要があります。
なお Windows ユーザでもネスケ用の Flash Player しかインストールしてない場合には、影響を受けません。IE用の古いフラッシュがインストールされているかどうか確認するには、ファイル名 flash.ocx で検索してください。もしあればインストール済みということになります。ネスケユーザなども、念のために(ネスケ版Flashを)最新版にバージョンアップしとけば間違いないです。
動画を MediaPlayerコントロールとしてHTMLにうめこむ場合のヒントとして、「ActiveXが使えない環境でも困らない」「ActiveXをオフにしている環境で警告ダイアログが出ないようにする」「停止状態で動画中のひとこまが静止画で見えるようにする」という3つの Tip を説明します。アクティブスクリプトについての予備知識を前提とします。
現在、動画のファイルをウェブで公開する場合、そのファイルへのリンクという形にしていることが多い。しかし、次の図のように(ふつうのイメージと同じように)ページ内に画像を埋め込みたい場合もある。(以下は動画コントロールの例の画像で、これ自体は、ホンモノのコントロールでありません。説明のためのただの絵です。)
動画再生用のコントロールが埋め込まれたページの例
つまり、映画やアニメについてのレビューを書くような場合、ウェブページの内部に、引用したクリップを再生できる小さな窓があれば、引用箇所とその部分についてのコメントを見比べやすく、分かりやすい記事になるだろう。また、何かの説明に動画を用いる場合も、説明の文章と動画がすぐそばに並んでいるほうが、見やすいだろう。外部リンクにしても本質は同じだが、いちいちほかのヘルパーアプリのウィンドウを見なくても、ウェブページそのものの内部に画像が「ペースト」されていたほうがべんりだし、そのほうがウェブページのマルティメディアとしてのポテンシャルが発揮される。
けれど、この方法には、いくつかの注意点がある。
そこで、以下では、次のことがらについて説明する。
基本的に <object> を使って、必要な ActiveX が利用可能なら動画の埋め込み、無効なら代わりのイメージが表示されるようにする。いずれの場合でも、動画へのリンクを作っておく。ActiveX が無効の場合、直接リンクがないと動画にまったくアクセスできなくなってしまうから、その場合にリンクが必要になることは言うまでもない。けれど、IEで埋め込みが可能でも、動画をローカルにダウンロードしたり、なんらかの理由で埋め込みの窓より外部のヘルパーアプリを使いたい場合もあるだろうから、ActiveX が使える場合でも、リンクもあるほうが良い。概念的には、次のような感じになる。
<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95"> <!-- ActiveX が有効なら、次のパラメータで埋め込まれる --> <param name="FileName" value="clip.wmv" /> <!-- ActiveX が無効なら、次のタグが解釈される --> <img class="inset" src="clip1.jpg" width="160" height="120" alt="愛国戦隊大日本" /> </object> <!-- 直接リンク --> <p> Windows Media Video 8形式の動画クリップ 263KB: <a href="clip.wvx">ストリーミング(64Kbps)</a>, <a href="clip.wmv">非ストリーミング</a> </p>
なにをもって最善とするかは価値観の問題だが、この方法は、ぶなんなソリューションだろう。
上記の classid は古いほうの mplayer2.exe(MediaPlayer6)に対するものです。新しいほうの MediaPlayer の場合は、
CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
という値になるらしいが、手元ではうまく動かないし、mplayer2 のほうが軽いので、さしあたっては、これを使ってみました。
ActiveX を原則オフにしているかたならよくご存じと思うが、ActiveXがオフだと、ある種のコントロールを含むページを開くたびごとに次のような警告ダイアログがいちいちポップアップして、たいへんうざい。
上記のような動画のプレゼンテーションにおいては、ActiveX が有効であってくれたほうが、つごうがいい。けれど、だからといって、ActiveX が無効のユーザに対して、こんないやがらせのような警告をポップアップさせるのは、行儀が悪すぎる。このポップアップは、それとなしに ActiveX がオンでないのが悪いとほのめかしているが、オフならオフでかまわない。オフであるかもしれないことも考慮して、その場合でも、機能の低下が整然としたものになるようにするべきだ。
けれど、このポップアップは、IE(ないしWindows)自身が勝手に出すものなので、ウェブライターの側から直接、抑止できない。そこで、ActiveX がオフであれば、初めからこの <object> タグを見せないようにしよう。 <object> があると「オフだからダメです」と言われることが分かっているときには、 <object> を読ませない。そうすれば、うざい警告も出ない。
そのためには、まず ActiveX が有効か無効か調べて、有効な場合だけ、これらのソースを書き出せば良い。それには JavaScript が必要だが、JavaScript がオフになっているとしたら、たいがい ActiveX もオフになっているだろうから、JavaScript がオフの場合、つまり <noscript> が解釈される場合には、ActiveX は利用できないと仮定してしまって実用上、問題ないだろう。
したがって、問題は、ActiveX が有効かどうか、クライアント側スクリプトでどのように検出すればいいか?につきる。
navigator.javaEnabled() メソッドのような感じで、navigator.activeXEnabled() みたいなのが JScript の独自拡張にあれば速いが、そんなのがあるのかどうか、よく分からない。ここでは、次のような強引なハックを使う。すなわち――
ActiveXObject("Microsoft.XMLHTTP")
以上のアイディアを実装するにあたっては、IEのふりをするOperaを排除するように気をつけなければいけない。ただのIEエミュにすぎないOperaは、上のような強引なハックにたえられず、最悪フリーズしてしまう。Operaの場合、上記のチャレンジをスキップさせなければならない。以下のリストは、完全ではないが、ほぼ実用になるのでは……。IE以外や、IEでもActiveX が無効の場合には、平和に静止画が出力され、ActiveX が有効な場合のみ埋め込みが実行されるので、うるさい警告が出る可能性が低くなる。
var _ActiveX = false; var _Opera = false; for(var i=0; i<navigator.plugins.length; i++){ if( (navigator.plugins[i].name.toLowerCase()).indexOf("opera")>-1 ) { _Opera = true; // Opera6 } } var ua = navigator.userAgent.toLowerCase(); if( ua.indexOf("opera") > -1 ) _Opera = true; if( document.all && ua.indexOf("msie 4") < 0 && !_Opera ) { // MSIE5, 6... var hack = 'try{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");' + '_ActiveX=true;}catch(e){}'; execScript( hack ); } var d = document; d.write('<div class="clip">'); if( _ActiveX ) { d.write('<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95">'); d.write('<param name="FileName" value="clip.wvx" />'); d.write('<img src="clip.jpg" width="160" height="120" alt="" />'); d.write('</object>'); } else { d.write('<img src="clip.jpg" width="160" height="120" alt="" />'); } d.write('</div>');
この発想は真にエレガントでないし、試しに作ってみるオブジェクトが XMLHTTP というのも行き当たりばったりの感じだが、とりあえず、これで動く。もっと良い方法が見つかったら改訂します。良いアイディアがあったらこのへんに書いてください。
<script type="text/javascript"> var _ActiveX = false; var _Opera = false; function _debug( msg ) { document.write("<p>Debug: " + msg + ".</p>"); } for(var i=0; i<navigator.plugins.length; i++){ if( (navigator.plugins[i].name.toLowerCase()).indexOf("opera")>-1 ) { _Opera = true; // Opera6 } } var ua = navigator.userAgent.toLowerCase(); if( ua.indexOf("opera") > -1 ) _Opera = true; if( document.all && ua.indexOf("msie 4") < 0 && !_Opera ) { // MSIE5, 6... var hack = 'try{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");' + '_ActiveX=true;_debug("ActiveX Enabled");}' + 'catch(e){_debug("ActiveX Disabled");}'; execScript( hack ); } else { _debug("Not MSIE"); } </script> <noscript> <p>Debug: No script.</p> </noscript>
そんなこんなで、無事コントロールが表示されても、デフォルトのままだと、動画の表示部分が真っ黒だったり、次のように Windows のロゴが表示されている。
同じプレイスホルダなら、Windows のロゴなどより、初めにあげた例のように、「そこで再生可能な動画のなかのワンシーン」が静止画で出ているほうが好ましいだろう。
それを直接、指定できるパラメータもあるのかもしれないが、とりあえず以下の方法を試したらできたので、紹介します。
まず、パラメータで、
<param name="TransparentAtStart" value="true" />
を与えて、背景を透過させる。そのうえで、<object> の style属性で好きな背景画を指定する。ただそれだけです。
いちいち説明するより、以下のリストを見たほうが速いでしょう。
d.write('<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95"'); d.write(' type="application/x-oleobject" width="155" height="115"'); d.write(' style="border: inset thin; background-image: url(clip1.jpg)">'); d.write('<param name="FileName" value="clip.wvx" />'); d.write('<param name="AutoStart" value="false" />'); d.write('<param name="TransparentAtStart" value="true" />'); d.write('<param name="AutoSize" value="true" />'); d.write('<param name="ShowAudioControls" value="true" />'); d.write('<param name="ShowPositionControls" value="false" />'); d.write('<param name="ShowTracker" value="false" />'); d.write('<param name="AutoRewind" value="true" />'); d.write('<img src="clip.jpg" width="160" height="120" alt="" />'); d.write('</object>');
ここで object が読み込めなかったときに表示されるイメージと同じ静止画を object の背景に指定しておくと、ActiveX が使えた場合も使えなかった場合も同じようなページレイアウトになり、単に埋め込み機能が使えるか使えないか?だけの違いとなる。
このほか AnimationAtStart パラメータを false (既定値は true)にすると、再生ボタンを押してから再生が始まるまでの読み込み中に Windows のロゴが出るのも抑止できます。ブロードバンドの場合、そのほうがすっきりして良いでしょう。ナロウバンドの場合、このパラメータを false にすると読み込み中に画面が真っ黒な状態がつづいて不安になるので、ここでは既定値のままにしてあります。パラメータについての詳細は、Streaming Mpeg-4 from Your Website がたいへん参考になりました。
必要なスクリプトを clip.js として、実際のHTMLは、次のような感じになる。
<script type="text/javascript" src="/image/2002/aikoku/clip.js"></script> <noscript> <div class="clip"> <img src="/image/2002/aikoku/clip.jpg" width="160" height="120" alt="" /> </div> </noscript>
コードを実際にペーストしておくので、いろいろなブラウザで見てみてください。お気づきの点がありましたらおしえてくださいね。
実際に利用可能なコントロールとリンクです。64Kbps未満の帯域の場合は、完全にダウンロードしてから再生する非ストリーミング再生をご利用ください。
DAICON FILM「愛国戦隊大日本」(1982)より
Windows Media Video 8形式の動画クリップ 263KB: ストリーミング(64Kbps), 非ストリーミング
ActiveXコントロールが利用可能な環境では、次のように表示されるはずです。
(これは画像です。)
ActiveXコントロールが利用できないか、またはJavaScriptがオフになっていると、埋め込みコントロールのかわりに、同じ静止画がふつうに img で表示されます。「ActiveXが使えないので正しく表示できない」という警告ダイアログも出ず、ここに ActiveX を埋め込もうとしたという形跡自体が隠蔽されます。動画ファイルへのリンクのそばに、その動画の一場面のイメージが貼ってあるようにしか見えません。
以上のように、スクリプトを駆使することで、ActiveX が使えない場合の機能の低下を、整然としたものにすることが可能です。いずれの場合でも動画ファイル(この例ではWMV)ないしメタファイル(WVX)への直接リンクを利用でき、ActiveX が有効であればさらにページ内の埋め込み再生も利用できる、ってわけです。
動作確認: Windows 2000 SP2 + IE6 / Mozilla 1.0RC2 / Netscape 4.79 / Opera 6.02 build1090(Operaは不安定)
なお、.htaccess 等で設定すべき mimeタイプは、次のとおりです。
AddType audio/x-ms-wma .wma AddType video/x-ms-wmv .wmv AddType audio/x-ms-wax .wax AddType video/x-ms-wvx .wvx
ちなみに、ここでは使いませんが、<embed> タグを利用しつつもHTML4.01の仕様書に反しないようにする方法もあります。document.write のなかの文字列として扱えば良いわけです。Jpeg2000 の場合などどうしても <embed> が必要だけれど形式的には仕様書は守りたい、という考えの場合には、そういう方法も良いかもしれません。
愛国戦隊をめぐる記事を書こうとして、動画をページにうめこみたいと思ったら、上のような技術的問題に気づいたので、まず、それをいちおう解決したしだいです。本題の「愛国戦隊」論は、このあとに続きます。