Hatena::ブログ(Diary)

ぽりぴぃすらいと このページをアンテナに追加 RSSフィード Twitter

プロフィール

muddydixon

muddydixon

すきなものたれながし

カテゴリー
言及ISBN/ASIN
  • ディレクターズ・カット 燃えよドラゴン 特別版 [DVD]
  • クレイジー / ビューティフル [DVD]
  • 岩波講座 ソフトウェア科学〈〔知識〕15〉自然言語処理
  • Death Proof
  • ノッキン・オン・ヘブンズ・ドア [DVD]
  • 死ぬまでにしたい10のこと [DVD]
  • しゃべれども しゃべれども 特別版 (初回限定生産2枚組) [DVD]
  • かぶく者(1) (モーニングKC)
  • かぶく者(2) (モーニングKC)
  • ハライソ―笑う吸血鬼 2
  • レッド(1) (イブニングKCDX)
  • マジで儲かる5秒前!知らないあなたが大損しているタウンページ戦略法
  • DS文学全集
  • DS文学全集
  • フロム・ダスク・ティル・ドーン [DVD]
  • ノッキン・オン・ヘブンズ・ドア [DVD]
  • 時計じかけのオレンジ [DVD]

2012/07/12(Thu)

Data::ObjectGeneratorを作りました

| 00:10 | Data::ObjectGeneratorを作りましたを含むブックマーク Data::ObjectGeneratorを作りましたのブックマークコメント

muddydixon/Data-ObjectGenerator ? GitHub

ソーシャルゲームとかアクションログとかそういったものの解析を頼まれたりしたけど、

相手方の仕様が詰まり切ってなかったり、絶賛開発中で「ごめん、ログまだ出せないわ〜」って

状況ってあると思います。

途中でも仕様を聞きだして、サンプルログを作らないと解析もできないし、

集計結果をグラフ化もできないですよね。

そんな時に、次みたいな適当なスクリプトを作ってもいいんですけど

$ perl -MJSON -e 'my $json = JSON->new; for(my $i=0;$i<10000;$i++){print $json->encode({uid=>int(rand()*1000), time => time - int(rand() * 3600 * 24 * 7})."\n"; }'

同じサンプルログをチームでシェアしたいです。そういう時には、下記のような

テンプレートファイルを作成して、gitで管理すれば、同じサンプルログをチームでシェアして

開発をすすめることができます。

{
    "user_id" : {
        "type": "Number"
      , "min": 50
      , "max": 100
    }
    , "user_name": {
        "type": "String"
      , "pat": "Cccnnnnn"
    }
    , "time": {
        "type": "Number"
      , "min": 1341367130
      , "max": 1341971912
    }
    , "tag": "sample"
    , "type": {
        "type": "Enum"
      , "items": ["hoge", "fuga", "piyo"]
    }
    , "register_hour": {
        "type": "Number"
      , "min": 1341367130
      , "max": 1341971912
      , "round": 3600
    }
    , "average": {
        "type": "Number"
      , "min": 100
      , "max": 500
      , "isDouble": 1
    }
}

そんでもって

$ perl ./bin/datagen.pl -t sample.json -n 10 -f csv
average,register_hour,tag,time,type,user_id,user_name
101.062767948852,1341475200,sample,1341543083,piyo,56,Zmy23857
446.95941709805,1341435600,sample,1341405922,piyo,89,Zwd19833
406.173929082109,1341849600,sample,1341511917,piyo,64,Krp21332

$ perl ./bin/datagen.pl -t sample.json -n 3 -f json 
{"register_hour":1341478800,"average":240.581803392516,"time":1341701075,"type":"fuga","tag":"sample","user_id":76,"user_name":"Lvo08081"}
{"register_hour":1341871200,"average":140.299695887451,"time":1341497759,"type":"hoge","tag":"sample","user_id":87,"user_name":"Ynq76984"}
{"register_hour":1341428400,"average":160.925643773629,"time":1341720064,"type":"hoge","tag":"sample","user_id":50,"user_name":"Plo39381"}

$ perl ./bin/datagen.pl -t sample.json -n 3 -f fluentd
2012/07/12 23:56:51 +0900 test: {"register_hour":1341493200,"average":315.102245096014,"time":1341407924,"type":"fuga","tag":"sample","user_id":66,"user_name":"Nqs20784"}
2012/07/12 23:56:51 +0900 test: {"register_hour":1341802800,"average":173.608217359369,"time":1341696936,"type":"piyo","tag":"sample","user_id":56,"user_name":"Mtq98875"}
2012/07/12 23:56:51 +0900 test: {"register_hour":1341694800,"average":320.58444067265,"time":1341890346,"type":"fuga","tag":"sample","user_id":66,"user_name":"Tgj88138"}

のようにいろんな形式でログを標準出力に出すことができます。

ログ作成計画

1種類のログであれば、正直、うえのCPANインストールすることを考えれば、1 linerで書きます。

でも、往々にして、「ユーザのマスター」「アイテムのマスター」「購買ログ」みたいな何種類ものログが必要になりますし、それぞれをhiveとかで集計したことにして、「分単位」「時間単位」「日単位」みたいなログも必要になります。

その時に便利な機能がplanです。

下記のようなJSONをplan.sample.jsonという名前で保存します。

{
    "file": {
        "file": "./sample.json"
      , "num": 1000
      , "output": "payment.log"
      , "format": "json"
      }
    , "stdout": {
        "file": "./sample.json"
      , "num": 10
      , "output": "stdout"
      , "format": "csv"
      }
    , "fluentd.log": {
        "file": "./sample.json"
      , "num": 10
      , "output": "stdout"
      , "format": "fluentd"
      }
    , "fluentd.forward": {
        "file": "./sample.json"
      , "num": 10
      , "output": {
          "type": "fluentd"
        , "tag": "test.mogumogu"
        , "host": "localhost"
        , "port": 24224
        }
      }
    , "mongo": {
        "file": "./sample.json"
      , "num": 10
      , "output": {
          "type": "mongo"
        , "host": "localhost"
        , "port": "27017"
        , "db": "test"
        , "collection": "mogumogu"
        }
      }
    , "mysql": {
        "file": "./sample.json"
      , "num": 10
      , "output": {
          "type": "mysql"
        , "host": "localhost"
        , "port": "3306"
        , "db": "test"
        , "table": "mogumogu"
        , "user": "root"
        , "pass": ""
        }
      }
}

これは、第一階層のキーが、作業名で、fileがテンプレートファイルです(前述)。numはログのレコード数です。

outputの部分に出力形式を指定します。

現在は

の5種類に対応しています。

各種設定はplan.sample.jsonを参照してください。

さあ、大量のログを作って解析をしましょう!

TODO

  • ちょっとしたプログラムを埋め込みたいので実装しています(テストも終わってます)
  • 変数とかextendsとかやらないとコピペが大量に行われるのでうんざりしています(途中まで)
{
  "$time": {
       "type": "Number"
     , "min": 100
     , "max": 10000
  }
  , "checkin": $time
  , "checkout": {
       "extends": "$time"
     , "round": 160
  }
}

とか、親ファイルを指定して、オプションを上書きしていく仕組みとかいれて、仕事を楽にしたいです。

fluent-plugin-datacalculatorを作りました

| 00:43 | fluent-plugin-datacalculatorを作りましたを含むブックマーク fluent-plugin-datacalculatorを作りましたのブックマークコメント

muddydixon/fluent-plugin-datacalculator ? GitHub

fluent-plugin-datacalculator | RubyGems.org | your community gem host

id:tagomoris さんのをパクってインスパイアされて、簡単な演算をしながら指定した時間単位で集計をしてくれるプラグインです。また、特定のキーの組み合わせを1つのレコードとして出力することもできます(aggregate tagではなく、aggregate keyのイメージです)

match payment.quest>
  type datacalculator
  tag result.quest
  count_interval 5s
  aggregate keys area_id, mission_id
  formulas sum = amount * price, cnt = 1, total = amount
  finalizer ave = cnt > 0 ? 1.00 * sum / cnt : 0
  <unmatched>
    type file
    path unmatched
  </unmatched>
</match>

この設定ファイルのfluentd

{area_id: 3, mission_id: 1, amount: 1, price: 300, item_name: "回復薬大"}
{area_id: 2, mission_id: 3, amount: 3, price: 200, item_name: "回復薬中"}
{area_id: 3, mission_id: 1, amount: 5, price: 100, item_name: "回復薬小"}
{area_id: 1, mission_id: 1, amount: 1, price: 300, item_name: "回復薬大"}
{area_id: 1, mission_id: 1, amount: 3, price: 200, item_name: "回復薬中"}
{area_id: 2, mission_id: 2, amount: 5, price: 100, item_name: "回復薬小"}

みたいなのを流すと

{area_id: 3, mission_id: 1, sum: 800, cnt: 2, total: 6, ave: 400}
{area_id: 2, mission_id: 3, sum: 600, cnt: 1, total: 3, ave: 600}
{area_id: 1, mission_id: 1, sum: 900, cnt: 2, total: 4, ave: 225}
{area_id: 2, mission_id: 2, sum: 500, cnt: 1, total: 5, ave: 500}

のように集計されて出てきます。

複数のCPUのログを足しあわせたどうのこうの、とか、購買ログがどうのこうのとか、そういう人は試してみてください!

トラックバック - http://d.hatena.ne.jp/muddydixon/20120712

2012/06/30(Sat)

jQuery 1.8 beta 1 のXSSのところの追記

23:27 |  jQuery 1.8 beta 1 のXSSのところの追記を含むブックマーク  jQuery 1.8 beta 1 のXSSのところの追記のブックマークコメント

jquery1.8 beta 1が出ました - ぽりぴぃすらいとを書いたところ、mentionがたどれなくなってしまったのですがtwitterで「fixとはどういう状態ですか?」と聞かれたのでコメントを見てみました。

そもそもの状態

まず、チケットの9521ですが、malaさんの指摘部分を含んではいますが、大枠(validなものとして)入力を受け付ける、ということとしてfixし、11617に渡しています。

そこで、no titleこのように「いやいや、解決してないよ!?」と投げ込んだんですが、そこでは

Use case: rich editor in an iframe/div with contentEditable enabled, user paste some unknown html (word maybe) and we only want to allow the strong tag and remove or rename the others tag. This would be useful for many wyswyg html5 editors.

Use case: ユーザが未知のhtmlを貼り付け、強調タグやその他のタグを削除・変更することだけを可能にしたい、contentEditableが有効になっているiframeやdiv内のリッチエディタ。これは、多くのwyswyg html5エディタで便利だろう。

とコメントが返されています。

確かに便利だけど、なんだかなぁ、という気もします。そもそも.prop()とか.attr()があるんだから、relとかそういうのはそっちのAPIから指定するのがいい気もするけど、確かにそれだと、wyswygだときっついよなぁとは思います。

こういうやりとりの次に、dmethvinが #11617 (Define a $.parseHTML method for creating HTML fragments) ? jQuery Core - Bug Trackerで下記のように答えています

To clarify the purpose of this method, it is beginning the process of separating the two String cases that $() handles: selectors and HTML serialization. There was some discussion in #11974 that implied it may be misunderstood as some sort of "XSS-proof HTML processing." It is not.

We want to mitigate the chances that a jQuery dev calls $(selector) thinking it is a CSS selector, but Mr. Bad Guy has managed to get script into selector and therefore executes it. We're doing that by providing $.parseHTML and eventually locking down the HTML recognition of $() to a small subset.

If/when environments provide better ways to sandbox, the ability of $.parseHTML() to make the dev's intentions clear will come in handy. However, no matter the method, jQuery allows devs to parse and execute scripts. If they process complex HTML with script and allow that script to come from untrusted or corruptible sources, it is still possible to make successful XSS attacks--just as it would be if the dev wrote their code in bare DOM methods.

ざっというと

  • $() の2つの文字列ケースを分けて考えよう。1つは、selectorでもう一つがHTML serialization
  • #11974でも議論されてるけど、"XSS-proof HTML processing" じゃないよ
  • selectorを想定している$(selector)で、悪意ある開発者によって、selectorにスクリプトが混入され、それが実行される機会を減らしたい
  • そのために、$.parseHTMLを提供し、最終的には、$()におけるHTML識別をlock downしたい
  • サンドボックス環境において、開発者の意図を明確にする$.parseHTMLの機能は役に立つと思う

と、まあ、malaさんがjQueryにおけるXSSを引き起こしやすい問題について - 金利0無利息キャッシング ? キャッシングできます - subtechで書かれてる通り、selectorでもHTMLparserとしても機能するってのがXSSの混入を起こすから、両者を分けていこうと考えている(と僕は読み取っています。間違ってたらコメントください。)

んー

HTMLparserの機能がwyswygなどで重宝されるとはいえ、XSSの温床になるのは避けられる限り避けたほうがいいと思うので、

  • $.parseHTML: 自由に記述が可能
  • $.tag: 従来のHTMLタグ生成機能
  • $(): selector

みたいな形で明確に分けて、通常は$.tagと$()を使うようにできればいいような気もします。

追記 2012/07/01

自分の拙い理解の中ですが、コメント頂いたので、補足しておきます。

上で、

selectorでもHTMLparserとしても機能するってのがXSSの混入を起こす

のようにmalaさんのブログを引きましたが、

で、自分の理解(というか今後の.parseHTML含めての解釈・予測?)では、そもそも、こういう「一時的に[]や''の中にタグが入っているときにCSSセレクタと見なされる」が起こっているのは2つの機能を切り分ける時の識別ルールが煩雑になってしまうことが理由なんだと思っており、そもそも、2つの機能を同じメソッドに詰め込むことが良くないんだと。

.parseHTMLはそれらの機能を明確に識別する方向に進むよ!というのが、まさに #11617 (Define a $.parseHTML method for creating HTML fragments) ? jQuery Core - Bug Trackerのコメントに現れてるんだと思いました。

トラックバック - http://d.hatena.ne.jp/muddydixon/20120630

2012/06/23(Sat)

jquery1.8 beta 1が出ました

| 04:00 | jquery1.8 beta 1が出ましたを含むブックマーク jquery1.8 beta 1が出ましたのブックマークコメント

2012/06/30 XSSについて追記しました

jQuery 1.8のbeta 1がリリースされました。

このバージョンではcustom buildが可能になる「modularity」という機能が追加されました。

この機能により、ajax, css, dimensions, effects, and offsetという機能を除外したjquery.jsをbuild可能になります。

最小セット(すべてを除いた)ではminifiedかつgzip化された状態で28KBまで小さくなるようです。

個人的にはnodeなどでの利用を考えて、domの部分(sizzle)を選択可能にして欲しいところではありますが、underscoreなどのことも考えると、その部分はlibraryレベルでの使い分けをするほうがよさそうです。

MODULARITY

grunt.jsを利用し、custom biildを行うことができます

$ grunt custom:-ajax

とすることで、ajax機能を除外したバージョンをビルドできます。

手元で、確認したところ、$.getを見るとundefinedになっています。

VENDER-PREFIX CSS PROPERTIES

デザイナを含めて頭痛の種である、VENDER-PREFIXに対して、ブラウザに応じた適切なPREFIXをつけてくれる機能が実装されました。

これにより、

$("#myscroll").css("marquee-direction", "backwards")

と記載することで、例えば、Chromeを使っていた場合、CSSには、「-webkit-marquee-direction: backwards」と適切なPREFIXが付けられます。

ANIMATION (EFFECTS)

これまでの経年により入り組んでいたコードを今回のバージョンで綺麗にし、統制下(笑)に置きました。

これにより、animationを追加したり、改変することが可能になります。

jquery-uiを入れるほどではないけど、もう少し色々したいなぁってことは多かったので、この機能も個人的にはすごく嬉しい機能です。

今回は事前資料も用意しているようです。

SIZZLE CSS SELECTOR ENGINE

SIZZLEのmajorな書き直しも今回のバージョンで入り、パフォーマンスに大きな改善が入ったようです。

パフォーマンスを見ると、Operaたんで、すごい改善されているようですね。

具体的なコードは後で追いたいとおもいます。

XSS PROTECTION

$() methodでscriptタグ作るとinlineでscript記述できてしまいました。このようなケースは、jQueryを利用していようといまいと、多くのサイトで見られました。

1.8の次のバージョンである1.9で$()の役割をより厳しくする予定です。

今回の1.8では明確にHTMLとしてparseされることをユーザに知らせる$.parseHTMLを追加しました。

この挙動を少し見てみると

      console.log($.parseHTML('<script></scr'+'ipt>')) // -> [<script></script>]
      console.log($.parseHTML('<script>')) //-> [<script></script>]

      console.log($.parseHTML('<script src="./hoge.js"></scr'+'ipt>')) // -> []
      console.log($.parseHTML('<script>alert(1)</sc'+'ript>')) // -> []
      console.log($('<script>alert(1)</sc'+'ript>')) // -> [<script>alert(1)</script>]

なんかよさそうですが、malaさんが出された報告の一番最後のコメント

      var param = "]<img src='/' onerror='alert(1)'>[";
      console.log($("a[rel=" + param + "]"))
      console.log($.parseHTML("a[rel=" + param + "]"))

に対しては、全然変わらず、XSSが残されています。

fixされてて #11617 (Define a $.parseHTML method for creating HTML fragments) ? jQuery Core - Bug Trackerに問題は移されたらしいんですが、こちらもfixされています。

なんでだろう。

でも、まあ、コメント見ると、$()が厳しくなるようなので、エンドユーザにとってはいいことだと思います。

SPRING CLEANING

trip hazzardをなくした、って書いてあって、repoが貼ってあるんですが404とかどういう罠ですか?

$.browserを1.9で無くします。そのかわりpluginを使ってください。

$.subは、便利さとかロバストネスを示せませんでしたw 1.9のcompatibilty pluginつかってください。

まとめ

modularityはもう少し粒度が細かいほうが嬉しいような気がするし、結局、全部込みで使う気がします。

ANIMATIONを含めた意味でCSS VENDER-PREFIXはかなり嬉しい気がします。

ざっと1.7rc2とのdiff見ると、全然別物っぽくなってますし。

XSSは古いものが動くようにすることも大事ですが、エンドユーザが守られる方に進むのは素晴らしいことだと思います!