書く内容の方針とかはフラフラしているのです。あまり考えていないかも知れません。面白いなぁと思うこと、大事なことだなぁと思うことを書いています。あんまり悲しいことは書かない主義。
ふと思いましたけれども、innerHTMLが危ない件。はせがわさんの例の記事で、innerHTMLを使わずにDOM操作でクローンノードを作れば吉みたいな部分。で、その後、別の誰かが別の場所でd=document.body.innerHTML;d=d+"<p>この記事おしまい</p>"などと記述したらオジャンではないのかなぁと。確かめていませんが。で、応用編の妄想ですが、Ajaxなチャットでd=d+"";みたいなリフレッシュってしてないよね?とか。うーん。そもそもはせがわさんの記事ではinput要素が例題になっていましたけれど、object要素あたりでも発生するのかなぁ?というのはですね、一時期、IEでパッチがあたってobject要素が表示されなくなってしまい、さぁユーザのみなさん、動画が見たければクリックしてアクティベーションしてくださいな、という事件がありませんでしたっけ?と悪い頭で思い出してみるのです。既存のウェブページを多量にかかえているウェブサイト管理者の皆さんがどのように修正したのか私にはよくわかりませんが、たぶん、body要素の一番最後にscript要素を書いておいてdocument.all配下のすべてのobject要素のみ、何か.innerHTML=何か.innerHTMLとかしてやるだけでオッケーみたいな一部ではやった?技があったような(遠い目)で、そういったページで何かobject要素の属性がバッククヲートで汚染されるとまずい?いや、innerHTMLが危ないのはinput要素だけならいいのですが。想像の世界だけでものをいうのはやめなさいと小さいころからおかぁさんによく叱られたものですが、ごめんなさい。試してみてません。
前回の日記で一部で顰蹙をかったhoshikuzuがまたもやみなさんにお届けする無駄日記の時間がやってまいりました。(……くまだまさし風……)
前回は無知もあらわにsetTimeout('VBScript記述',timer値,'VBScript')で大喜びしていたわけですが、「そんなんだめじゃん」とか言われました。orz
で、こうしなさいと。
以下JScript記述だよ
window.execScript('VBcript記述','VBScript')
おお!立派なしいたけを花咲かせることができそうです。さっそく、VBScript内でDIMを切ったbinXにJavaScriptでは生成できないはずのピュアなバイナリ値を1バイト、格納しましたよ。でJavaScriptの世界に舞い戻ってbinXをalertしてみて、ふむふむと満足な気分に。と、、、ところが。alert(typeof binX)をしてみてビックリ。答えは「unknown」ですって。あんたはunknownなオブジェクトでもalertできるのか!ってJScriptを頬擦りしたり殴ったりしたくなりました。ネット検索してみたら、基本、ピュアなバイナリ値をJScript側で操作できないそうそうであります。。がっくし。orz…がっくし。いや、せめて3バイトくらいのバイナリデータを直接DOMに流し込んでみたかったのですが、あはーん。断念か? なお、IEでは、ISO-8859-1というcharsetを指定しても内部的にはCP1252で処理しているっぽい…なのだそうであります。このへん、DOSプロンプトレベルと違うっぽい気がしますが。chcpのとりあつかいあたりと。ま、おかげさまで、ピュアなバイナリ値をJScriptで取り扱うことができない領域があるのでございます。0x80あたりからえんえんと。おいこら、UNICODEに化けるな!違うところにマッピングされるな!と殴りつけたいのであります。補助漢字の取り扱いをみたいだけなのに。どうしてくれよう。
//Stringオブジェクトをだましてjoinする
var strA = new String('el');
var strB = 'va';
var strC = Array.prototype.join.call(strA,strB);
alert(strC);
ってまだよく試してませんが、たぶんブラウザごとに挙動が違うと思われます。evalがalertされるといいなぁ…Firefoxの場合、for(var x in strA){alert(strA[x])}で腰を抜かしたのですが。上のコードは適宜なおさないといけないかもしれません。ごめんなさい。
※自分へのメモ。あとで上の方法に似たやつで、くだんのバイナリな謎オブジェクトをだますこと。あ、そうか、IEではだめなのかな?VBが使えないとなぁ…。
本物のJSON記法では文法的にはJSONオブジェクトとかいうのを使っていて、これはObjectリテラルのサブセットになっているのだそうです。だから、安易にObjectリテラルを使ってJSONでございます、とかは言えないと聞きました。
本物の一例
{ "Latitude" : "37.7668" }
偽物の一例
{ Latitude : "37.7668" }
keyの部分が文字列になっていて『"』で括られているのが本物の証。偽物のほうは、識別子になっちゃっています。ずいぶんと売れたと思いますけれど、書籍『Ajax イン・アクション』あたりではこのへんがすこぶる怪しいとか聞きます。さっきこの本をながめましたけれども、見た限りでは確かに。ま、evalった結果は同じになるようにみえるので構わないではないかという説も聞くところによれば、あるらしいのです。うぅむ。でもそんなことを聞いたら、JSON記法の産みの親たるダグラス・クロックフォードさんはきっと悲しいと思います。ええと。ところで。
{
label : ステートメント
}
上のような感じで、ブロック文にラベル登場!とかいう表現と、偽物JSON記法がどこか似ていることは明らかです。あくまでも私的推察ですがクロックフォードさんはこのことを避ける為に、オブジェクトリテラルのサブセットとして本物の記法を定めた…というのも、ひとつの理由ではないかと。なお、こんなんじゃなくて、全く正統な理由をHawkさん(jsphonの作者さん)による優れた記事にまとめらていたんですけれど、今はサイトが廃止されていて探しきれませんでした。残念。hawklab.jpのはず。webアーカイブも探したのですけれどね。
さて。表題、『偽物JSON記法はJSONハイジャックに弱いかもしれない』と私が感じたわけですが。Objectクラスを書き換えてのJSONハイジャックを実験的に試みてみたところ、偽物のほうはどうも簡単に陥落してしまうという傾向を見出したからです。 偽JSONデータの階層の下の方で配列に格納された偽JSON連想配列が簡単にアクセスできてしまいます。その配列の親までの連想配列が、さきほど書いておいた「ブロック文にラベル登場!」とみなされてしまうからです。その反対に配列の中身ではラベルとはみなさないようです。あぁ!これでは簡単すぎます。
本物JSON記法なら絶対大丈夫、ということを主張するわけではないのですが、偽物では敷居がすこぶる低いなぁと感じた次第です。
偽JSONデータの例
{ResultSet:{Result:[{precision:"zip",Latitude:"37.7668",Longitude:"-122.3959",Address:"",City:"SAN FRANCISCO",State:"CA",Zip:"94107",Country:"US"}]}}
このままじゃ動きませんけれど
var Object = function Object() {
var foo = this;
var bar = function() {
var ret = "";
for(var x in foo) {
ret += foo[x] ;
}
alert(ret);
};
setTimeout(bar, 100);
}
これでLatitudeあたりをクロスドメインで参照できるかもです。偽JSONですから。