記事一覧

RSS 1.0とは何だったのか

RSS 1.0におけるrdf:aboutとかlinkにまつわるあれこれ

久々にお勉強エントリ。

きっかけは、SiReFaSoValidation Checkにかけてみて引っ掛かってしまったため。HTML5の文法チェックのつもりで、HTML自体はValidだったのだけれども、RSSがInvalidと判定されてしまった。(CSSもInvalidなのだけれども、モダンブラウザのCSS3先行実装などを利用しているためそこは諦めている。早く仕様が固まってprefix取れるといいな。)

引っ掛かったのはRSS 1.0。item要素のrdf:aboutの属性値が他のitem要素のものと被ってる、とのこと(rdf:aboutはユニークでないといけない)。以下はこのblogのRSSの一部。個別記事にはユニークなURLが割り当てられている。

<item rdf:about="http://home.384.jp/evidence/cgi-bin/archives/84.html">
<title>SiReFaSo更新</title>
<link>http://home.384.jp/evidence/cgi-bin/archives/84.html</link>
<description>SiReFaSo更新
今までNTCのデータをコピーしてるだけでしたが、NTCのデータが飛んだ時に共倒れとなってしまうので、単独で巡回・更新捕捉出来るようにしました。
SiReFaSo - 伺かゴースト更新フィード
新規登録ゴーストを @sirefa...</description>
<dc:date>2010-06-13T17:38:00+09:00</dc:date>
</item>

SiReFaSoは他にRSS 2.0とAtom 1.0を出力しているがそちらはValid。この2つは既存のPythonのライブラリを使っているので仕様をあまり知らないまま出力してるけれども変なことにはなっていない。問題はRSS 1.0で、これを出力するPythonのライブラリをかなり頑張って探したのだけれども見つからなくて、自分でテンプレートを書いて出力している。元になっているのはNTCのRSS 1.0(こちらはPHPのライブラリを使って出力している)。

本当はSiReFaSoではRSS 1.0は捨てようと思っていた。あえて自分で書いてまで出力しているのは単にNTCとの互換性を保持するため。しかし泣き言を言っても始まらないのでどう修正したものか考えてみた。

rdf:aboutには何を書くべきか

今まではrdf:aboutにゴーストの配布元サイトのURLを書いていた。RSSリーダーで購読する場合もリンク先には配布元を指定して直接飛べる方が便利だろう。しかし同一作者のゴーストが複数あった場合、配布元サイトURLは同じである場合が多い。これによって同一URIを複数itemのrdf:aboutに指定してしまい、Invalidとなっていた。

rdf:aboutはitem毎にユニークでなければならない。SiReFaSoに登録されているゴースト毎にユニークなキーはhomeurlだけだ(ゴースト名は重複を許容している)。つまりrdf:aboutにはhomeurlを指定するのが相応しい。でもちょっと待って。RSSリーダーで購読する際にhomeurlに飛ばされても誰も幸せにならない。大抵は404 Not Foundだ。GHOSTのルートフォルダにindex.htmlを入れてる人なんてそうはいない。てか、そこは配布ページじゃない。

ここで更なる疑問を抱く。item要素のrdf:about属性には一般的にURLを記述するが、item内にもlink要素というものを指定する。普通はrdf:aboutと同じURLを記述するようだが、異なっていても構わないらしい(互換性のために残された仕様?RSS 2.0にもlink要素がある)(そしてこれはユニークである必要がない)。一般的なRSSリーダーはどっちを読むのだろう?自分が作るとしたらRSS 2.0互換を考えてlink要素を優先するだろうなぁ、などと考えながらとりあえずRSS 1.0でrdf:aboutとlink要素にそれぞれ違うURLを指定してそのXMLをIE8、Firefox3.6.8、Opera10.60で表示してみた。以下がその結果。

  • IE8: link要素のURLを使用
  • Firefox3.6.8: link要素のURLを使用
  • Opera10.60: link要素のURLを使用

rdf:aboutはユニークであれば何でもいい、という結論。でもhomeurlを指定するのはやはり抵抗がある。rdf:aboutを使って何かするエージェントがいないとも限らないし…。

RSSのitemのlinkに他所様のURLを指定するのでなく、自分のサイトの構造を定義してマークアップできたらベストだろうか。SiReFaSoにはゴースト毎の個別ページを実装すべきだったかもしれない。とりあえずゴースト名で検索した結果のページのURLをrdf:aboutに指定することにする。一般的なRSSリーダーはlink要素を読むだろうから今まで通り利便性は損なわれないし、仮にrdf:aboutを読んで検索結果に飛ばされてもあらためて配布元へのリンクが示されたページを拝めるし、rdf:aboutはユニークになる(ゴースト名の重複は許容しているけどゴーストマスタの良心を信じることにする)。

他のサイトはどうしてる?

マッシュアップ系のサイトでは同じような問題を抱えているのではないだろうか。RSS 1.0を配信している他所様のサイトもValidation Checkしてみた。

自分のサイト内の記事であればパーマリンクもユニークだろうけど、やはりというか、他所のリンク集的なものや自由投稿形式のものはURI被りまで想定していないようだ。ちなみにいずれもrdf:about属性とlink要素内テキストは同一のURLが指定されていた。あえて別々のURLを指定するのも今回のような特殊な事情が無い限りするべきではないかもしれない。

SiReFaSo更新

SiReFaSo更新

今までNTCのデータをコピーしてるだけでしたが、NTCのデータが飛んだ時に共倒れとなってしまうので、単独で巡回・更新捕捉出来るようにしました。

SiReFaSo - 伺かゴースト更新フィード

新規登録ゴーストを @sirefaso に出力するようにしました。

http://twitter.com/sirefaso/status/16056591859

NTCmanager更新

フォルダ名がinstall.txtに記載されているものと違う場合に警告を表示するようにしました。

カンマを含む文字列の取得に失敗していた不具合を修正しました。

NTC同様、更新情報が取得出来なくなったGHOSTは自動的に削除されますが、SiReFaSoの方は取得出来なくなった時から24時間の間データを保持しています(NTCは3時間)。

登録したゴーストの立ち絵が表示されない場合は時間をおいてもう一度登録すると反映されるかもしれません。そもそも立ち絵が無い場合や画像形式が特殊な場合は反映されません。

NTCの方は登録データ全部読み込ませるという荒業で一ページで検索も全て完結させてきましたが、登録データが増えてきたのでそろそろ限界かもしれません(そのためにSiReFaSoで作り直しています)。

YAYA/AYAのコメントアウト

YAYA/AYA は /* と */ で囲まれた部分、および // から行末までがコメントアウトになります。

{
  /* コメント */
  //コメント
  'hoge'  //コメント
}

ハマリどころ

以下のコードは100,50,10のいずれかがそれぞれ3分の1の確率で返される関数です。

{
  100 //100円
  50  //50円
  10  //10円
}

上記と似ていますが、以下は100,5のいずれかがそれぞれ2分の1の確率で返されます。

{
  100 //100円
  50  //
  10  //10円
}

YAYA/AYA では改行前のスラッシュは改行無効の記号として処理されます。つまり上記のコードは以下のコードと等価です。

{
  100 //100円
  50  /  10  //10円
}

50 / 10 で 5 になります。

以下のコードは除算の対象が無いので tama.exe でエラーが確認できます。

{
  'hoge' //
}

tama.exe でエラーが確認できれば直しようがありますが、先述のように問題なく除算されてしまうと不具合原因の特定が困難になります。

ゴースト更新捕捉サイトの改装

NTC一周年

今日でNikola Tesla Centerが一周年を迎えました。不具合も多く味気ないサイトでしたが、方々でご紹介頂いたり、SSPの一括更新で利用して頂いたりと、嬉しいことの多い一年でした。あらためて感謝申し上げます。ありがとうございました。

移転のようなミラーのような

サーバが不調で見れなかったりすることもあり、機能の拡張性も無いので、別の所にミラーサイトのようなものを作りました。

Googleのインフラなのでたぶん安定していると思われます。

ゴーストに関する投稿を表示するUserJS更新

新サイトでも動作するように変更しました。通信を減らし、最適化して若干高速化されています。

無駄機能

新しく追加された機能がいくつかあります。

  • 検索でゴースト名・\0名・\1名・作者名の全てで検索するように変更
  • ゴーストの立ち絵の下に\0名・\1名を表示

検索結果ごとにRSS,JSON,JSONPなどが使えます。

任意の件数を取得可能です(通常は20件、負荷対策のため上限は200件としています)。

NTCについて

NTCの巡回内容をコピーしているだけなので、旧サイトもしばらく残しておこうと思います。いつかは単独で動作させることに挑戦したいです。

YAYAの関数TOAUTOを使うときは慎重に

YAYAの関数TOAUTOはちょっと危険

これのおさらいです。

前回までのおさらい

意図しない挙動の例
{
  TOAUTO('000123')  // => 123
  --
  TOAUTO('.')       // => 0.000000
}

使わなければ良いだけの話ですが、「はろーYAYAわーるど」などのテンプレートゴーストにはミドルウェアレベルで組み込まれています。具体的には、イベントのReferenceがTOAUTOを経由した状態でreference配列に格納されています。つまり、Reference0に"."が入っている場合でも、reference[0]を参照すると"0.000000"となってしまいます。

対策

最大の問題はTOAUTOの変換が「不可逆」であるという点です。"123"という値がreference[0]で参照出来ても、本当に送られてきた文字列が"123"だったのか"0123"だったのか"000123"だったのか判断のしようがありません。

なので不可逆な変換のみ無効とする関数TOAUTOEXを新たに定義しました。

{
  TOAUTOEX('000123')  // => 000123
  --
  TOAUTOEX('.')       // => .
  --
  TOAUTOEX('1') + TOAUTOEX('1') // => 2
}

TOAUTOEX
{
  _v = _argv[0]
  if TOSTR(TOAUTO(_v)) == _v {
    TOAUTO(_v)
    retrun
  }
  _v
}

yaya_shiori3.dicの414行目のTOAUTOをこのTOAUTOEXに置き換えることでreference参照の不具合を回避できます。

ゴーストに関する投稿を表示するUserJS更新

更新内容

  • 半分近くの投稿が表示されていなかった不具合を修正(これはひどい)
  • ゴースト名の横に投稿数を表示(Twitterは星、はてなハイクはハート)

ファイル 80-1.png

なんだか更新著しいのでuserscripts.orgの方にアップロードすることにしました。

Show UKAGAKA Ghost Reccomend

画像ファイルドロップで壁紙変更

HTML5的な何か

FirefoxはHTML5のFile APIという、ローカルファイルのドラッグアンドドロップに関する仕様に対応しているそうです。

DnDと言えば伺か的には壁紙変更ですよね。そこでHTML5の技術とは無縁なUJUに試しに実装してみました。

ファイル 79-1.png

UJU - Ujura and Uju

Firefoxでのみ、ゴーストに画像ファイルDnDでWebページの背景が変更されます。(右下の青いボックスの中の「うじゅら&うじゅう」でもお試し頂けます)

バグ修正

NTCmanager更新

一部のGHOSTのhomeurlが読めなくなっていた不具合を修正しました。

Nikola Tesla Center

ゴーストに関する投稿を表示するUserJS更新

特殊文字を含むGHOST名でエラーが発生する不具合を修正しました。

showghostrecommend.user.js

Help Ghost

サイト案内ゴースト

伺かゴースト更新フィードに何の説明もないのでうじゅら&うじゅうにヘルプ役を任せました。

ファイル 77-1.png

別個に解説ページとか用意したくない、余計なスペース取りたくない、ということで適任ではないでしょうか(選択肢にバグ抱えたままですが…)。officeのイルカ程度の存在感を発揮してくれればと思います。

里々の脆弱性をまとめてみた

何か色々勘違いしていた

里々で「らふらんす」を使う

里々のコードが外部から実行できるとかおかしいだろ常識的に考えて…。平たく言うと里々にバックドアが仕掛けられていたってことですね。なにそれこわい。

里々も更新されていますし、せっかくなので具体的な攻撃手法の例も併せて対策をまとめてみました。

利用者側で対策したい人のために(10/03/31 追記)

自動で里々を最新版に入れ替えて対策コードの書かれた辞書も生成するプラグインを作りました。
上記Wikiの一番下から入手できます。