Chrome App という、Chrome Extension の延長上にあるスタンドアロンアプリを作れる仕組みがある。これは、しばしば出てくる HTML + JavaScript でスタンドアロンアプリを作れるやつの Chrome 版にあたる。

結構いろいろとAPIが整備されていて面白いんだけど、いまいちテストを書く方法がわからなくていろいろ試した。Chrome の API を使っている場合、どうしても Chrome のコンテキストで実行する必要があり、なかなか面倒くさい。

protractor (webdriver-js ラッパ) を使う

protractor は Angular.JS 用のエンドトゥーエンドテストフレームワークで、いろいろ環境を一発でつくるのが便利なので使ってる。Angular.JS も使ってるから丁度いい。

コマンドラインから Chrome App を起動すると、まず1つ普通のChromeのウィンドウが開き、次にアプリケーションのウィンドウが開くという挙動をする。なので、アプリケーションのウィンドウが起動するのを待って、そっちにスイッチする必要がある。

403 Forbidden このあたりに書いてあるのをなおして、以下のようなのを書いた。

function switchToAppWindow (nth) {
	function _switchToAppWindow (n) {
		if (n <= 0) throw "failed to switch to app window";

		browser.driver.getAllWindowHandles().then(function (handles) {
			if (handles.length <= nth) {
				_switchToAppWindow(n--);
			} else {
				browser.driver.switchTo().window(handles[nth]);
			}
		});
	}
	_switchToAppWindow(1000);
}

switchToAppWindow(1) で2番目に生成されたウィンドウにスイッチできる。

これで、Angular.JS レベルでの E2E テストは書けるようになる

Unit テストを書く

しかし、E2E テストだと Chrome 向けに Chrome 専用の API を使ったライブラリのテストが書きにくいので、普通の Unit Test みたいなのも書きたくなる。

いろいろ試したけど、結局以下のようにした。

  • テスト用の .html を用意する
  • E2E テスト用のスクリプトから、executeScript でテスト用の .html を開き、テストを実行する

Jasmine を読みこませてテストを実行させ、自力でテスト結果を取得して表示してる。

ただ、罠があって、Jasmine が eval を使っててそのままだと Content Security Policy にひっかかって実行できない。これはmanifest.json に sandbox 指定することでも解決するけど、これだと本来の目的の API がたぶん使えないので、jasmine を書きかえて治す必要がある。global オブジェクトを取得しようとして eval を使っているので (なんで?) そこだけ自分で変えたら動く (Edge バージョンだと eval するコードがないので普通に動きそう)。

スケルトンプロジェクト

をつくった

  1. トップ
  2. tech
  3. Chrome App をテストする

500 Can't connect to stackoverflow.com:443 (certificate verify failed) の回答であったやつだけど、String.fromCharCode が複数文字を引数にできることを知った。String.fromCharCode、なぜか1文字しか渡せないと思いこんでいたので、なんとなくびっくりした。

console.log(String.fromCharCode.apply(null, [97, 98, 99]));
//=> "abc"

つまりこれは ArrayBuffer とかを String に変換するときにとても簡単に書ける。以下の例は 8bit のビューを作っているが、元記事のように必要に応じて 16bit のビューを作って渡すこともできる。

var buffer = new ArrayBuffer(10);
for (var i = 0; i < buffer.byteLength; i++) {
	buffer[i] = 97 + i;
}
console.log(String.fromCharCode.apply(null, new Uint8Array(buffer)));
//=> "abcdefghij"
  1. トップ
  2. tech
  3. JavaScript ArrayBuffer -> String 変換

あんまり日本語の文書だと見ない気がするけど、英語圏由来の文書だとしばしばみるような気がする Voltage Balun, Current Balun ってなんなのだろうと思って調べたけど、つまり以下のような話だった

  • 電圧バラン (Voltage Balun)
    • トランスとして働く (同時にインピーダンス変換が可能)
    • 強制バラン
  • 電流バラン (Current Balun)
    • コモンモードチョークフィルタとして働く (電圧は変更しない)
    • フロートバラン・ソーターバランとも呼ばれる

基本、電流バランで十分なら電流バランのほうが効率が良く、インピーダンスマッチも同時にしたいなら電圧バランを使う、でいいのかな。

  1. トップ
  2. tech
  3. 電圧バラン・電流バラン
  1. トップ
  2. ham
  3. 電圧バラン・電流バラン

買ってから1年とちょっと経過したが、U04 という乾燥フィルター掃除エラーが頻発し、フィルター周辺が結露するようになった。当然洗濯物がなかなか乾かない、というかエラーで止まるので乾燥がやりなおしになる。うちには物干し竿も洗濯バサミも存在していないので、死活問題

一通り念入りに、排水フィルタまでもを掃除してみたが改善されず、乾燥フィルタの奥が固定なので洗えないなーと思いつつ、ググってみると、メーカー修理すると脱着式になることがあるらしい。よくくるクレームっぽい。

ということですぐに修理を依頼して、来てもらったら、脱着式になった。丁寧にカラー両面の説明書までついている。乾燥時の騒音が増える?っぽいけど、乾かないことには仕方ないし、掃除しやすくなったので良かったと思う。とりあえず様子を見る。


ちなみに1年経過でメーカー保証切れだったけど、購入店 (ケーズデンキ) では価格に5年分の延長保証が含まれているので、支払いはしてない。事前に乾燥まわりで故障するであろうことが予測できたので、延長保証があるところを選んでたのは正解だった。

ケーズデンキを一度通してからの修理だったけど、今回かなりスムーズにいった。ケーズデンキの修理電話にかけると、購入時の電話番号を訊かれるので、それに答えれば購入履歴から保証情報もとってくれるみたいで、保証書は見せる必要がなく、その後はメーカー(パナソニック)から、日曜だったが当日中にコールバックがあった (とはいえ、電話をとれなかった)。特に待ちとかもなく、スムーズに終わってよかった。欲を言えば電話だと面倒なのでメールにしてほしい。


あと、メーカー修理の人曰く、洗濯漕クリーナーは、半分ずつ頻度をあげてやったほうがいいらしい。洗濯機が自動判定して余分な洗濯漕クリーナーを排水してしまうことがあるとのことだった。

あと、洗濯機入口の2mm〜4mm程度の狭い隙間から乾燥の風がでているらしく、そこも詰まらないように金属のクシとかで1年を目安に掃除したほうがいいらしい。

 -

4.0 / 5.0

しばしば、ただのサイン波を適当な周波数で出したくなると思いますが、ググってもいまいち一発で自分の欲しいものがでてこないので作りました。

  • サイン波
  • 矩形波
  • ノコギリ波
  • 三角波
  • ホワイトノイズ
  • ピンクノイズ
  • ブラウンノイズ

あたりを自由に組合せて出せます。(当然スマフォでも動く)

github https://github.com/cho45/WebAudio-Signal-Generator

  1. トップ
  2. tech
  3. WebAudio シグナルジェネレーター

そういえば最近8年前に作って放置していたヘッドフォンアンプを修理して使いはじめた。ネットで回路図が公開されていた SAITAMA なんちゃらみたいな名前がついたオペアンプ+ダイヤモンドバッファのスタンダードな回路のもので、いつのまにか片方聞こえなくなって使わなくなった、みたいな感じだったと思う。(当時の日記のエントリにリンクをはろうと思ったが読んでみたらキモ恥ずかしすぎるのでやめた…)

ちゃんと調べた感じ、単に入力の接触不良っぽかったので、とりあえずそれだけ直したら動いたんだけど、当時の自分のスキルレベルが異常に低くく (今も低いけど、今以上に)、アースまわりのワイヤリングに明らかにまずい部分があり、ちょっと試行錯誤して多少マシにした。

電源トランスを内蔵する仕様的に、当時はハムノイズが完全に消えなかったんだけど、アースまわりを常識的に直したら普通に皆無になった。8年経過の間に特にアナログ電子回路についてスキル上げした覚えがないけど、なんとなくベースレベルで解決した感じだった。

「ヘッドフォンアンプとか昔なんとなく作ったけど、意味あったのかなあ」と思って改めて使ってみたけど、音量あげたときの歪みっぽいものがなくなって気持ち良い感じにはなったので意味あるかもしれない。音量小さいなら意味ないしやっぱ意味ないのかもしれない。

Kazuho's Weblog: The JSON SQL Injection Vulnerability について。元記事をはっちゃめっちゃに要約すると

  • SQL::Maker にユーザから受けとったデコード済み JSON をそのまま突っ込むと SQL インジェクションになる場合がある
  • SQL::Maker 側でそういったことが起こらないように strict オプションをつけたから、できればそっち使え
  • 別に SQL::Maker に限らないから気をつけろ

という話っぽい。本来であればユーザ入力をタイプチェックをすべきだけど、クエリビルダレベルでも、脆弱性にならないようにもうちょっと考慮してもいいよねという趣旨かな…

strict モードは非互換なので、既存のコードが動かなくなる可能性があるようです。

Teng での対応

Teng を使っているとデフォルトで SQL::Maker がクエリビルダとして使われるので、同じように危険な場合があります。Teng 0.24 から、クエリビルダのコンストラクタにオプションを渡せるようになったので、以下のように書くと strict モードになります。

my $teng = My::DB->new({
    ...
    sql_builder_args => { strict => 1 }
});

Teng 0.23 以前の場合、このオプションがないので、以下のように自分で sql_builder に SQL::Maker のインスタンスを作って渡す必要があります。

my $teng = My::DB->new({
    ...
    sql_builder => SQL::Maker->new(driver => 'SQLite', strict => 1);
});
既に使っている場合

strict モードつきにしてみて問題なく動くならそのほうがいいですね。非常に単純なクエリは strict モードにしても変わりませんから、

$teng->search('foo', { id => $id })

みたいなクエリしか書いたことねーぞ! って場合、何も考えず strict を有効にして試してみると今後比較的穏かな気分でコードを書けることになります。

そうではない場合でも、あまりに大量にクエリビルダで複雑なことをしているというわけではない限り、 strict を有効にしてコードを書きかえ、検証しなおすべきでしょう。

さらに、どうせコード書きかえるなら根本的に入力のタイプチェックを行うのも考えたほうがいいと思います。


どうしても strict モードを有効にしたくないぐらい複雑にクエリビルダを使いこなしている場合かつ、脆弱性になりそうなコードを書いた覚えがあってヤバいぞという場合、ユーザから受けとる JSON などの構造化データを復号化するところで、一括して再帰的に全ての HashRef, ArrayRef, ScalarRef などを適当に bless することで、ある種の「汚染された」フラグとし、少なくとも SQL インジェクションについては防ぐことができると期待できます。

これは、SQL::Maker が strict オプションが入っていなくても、元から bless された構造化データについては文字列化が走るような挙動になっているためです。

ただ、これはこれでやはり全体的に影響する変更になるので、検証がstrict を入れる場合と同じように大変であり、コードを書きかえる手間の問題ないし、SQL インジェクションのリスクとほかのところで問題がでるリスクを比べた場合に、どうしてもとる1つの手段であって、基本は strict を有効にするように頑張ったほうが生産的かつ安全だと考えられます。

ユーザが構造化データを作れること

ウェブアプリケーション開発者は、普通のHTMLフォームが文字列しか送信できないという、歴史的経緯により無意識に、危険なデータは文字列でしかこないとなんとなく思っている。なのでユーザーが構造化データをつくって送れること自体がうっかり脅威になりえることがある。この手の問題は Perl に限らず Rails でも発生してる。

昨今では JSON をリクエストボディーにしたり、クエリ文字列にルールを与えて (例えば foo[bar]=1&foo[baz]=2 みたいな) 構造化データを受けとれるようにしたりといったことが行われる。これにより、信頼できない構造化データというのが生まれている。

単純なデータ構造でクエリを組み立てるというのは、それ自体が危険なAPI設計といえ、また、入力のタイプチェックをすれば防げる問題なので、それを強制するフレームワークになっているほうが良い、という学びを得られた。

  1. トップ
  2. tech
  3. ユーザ由来の構造化データによるSQLインジェクション

滅多にないことだと思うが、非常に大きな zip ファイルを動的に生成してダウンロードさせるみたいなことをしたいことがあるかもしれない。

Archive::Zip だとストリーム生成できないので、Archive::Zip::SimpleZip を使う。Archive::Zip::SimpleZip だとストリーム出力で file handle などに書き出せる。

これで一度ファイルに書いてから、そのファイルを sendfile 的にレスポンスしてもいいのだけれど、書いている間はクライアントからしてみれば完全に無反応になるので、場合によってはタイムアウトになってしまうことがある。そこでストリーム出力をそのままクライアントにストリームしたくなる。

簡単なコードにすると以下のようになった。Archive::Zip::SimpleZip にコールバックかオブジェクトを渡せたらいいが、渡せないようなので、文字列リファレンスをいちいちクリアしながら出力するキモいコードになっている。

#!plackup
use strict;
use warnings;

use Archive::Zip::SimpleZip qw($SimpleZipError :zip_method);

sub {
    my $env = shift;

    # Return streaming response
    sub {
        my $respond = shift;
        my $writer = $respond->([
            200,
            [
                'Content-Type' => 'application/zip',
                'Content-Disposition' => 'attachment; filename="dekai.zip"',
            ],
        ]);

        my $_buf = "";
        my $buf = \$_buf;
        my $zip = Archive::Zip::SimpleZip->new($buf, Stream => 1) or die "Failed to create zip file";

        for my $n (1..1000) {
            warn $n;
            $zip->addString("$n" x 100, Name => sprintf('%04d.txt', $n), Method => ZIP_CM_STORE) or die "SimpleZipError : $SimpleZipError";
            $writer->write($$buf); $$buf = "";
            select(undef, undef, undef, 0.01);
        }

        $zip->close or die "SimpleZipError : $SimpleZipError";

        $writer->write($$buf);
        $writer->close();
    };
}
  1. トップ
  2. tech
  3. Perl (PSGI) で zip ファイルを動的に作りつつ順次クライアントに送りつける

WebAudio 使ったモールス練習機を自分で作って使っているので公開する。

ほんとに全く聴きとれないときから使っているので、コッホ法というスタンダードなモールスの覚えかたに従って練習してくように作ってある。

見た目的に想像つくと思いますがスマートフォンでも動きます (Chrome for Android でだけ確認)。


コッホ法とは以下のような特徴のトレーニング方法で、無線電信の巧みと技にも書いてあるが、心理学者のルドウィグ・コッホさんが効率的にモールスを習得するための研究した結果を反映したもので、知られているトレーニング方法の中では唯一根拠があるといえそう。

  • 送信スピードは最低でも15wpm (word per minutes) 以上にする
    • 1文字の「符号」をまとまって認識するため
  • 最初は2文字だけから始まり、90%以上聴きとれるようになったら1文字足していく

最初は文字間の無音を長くして、だんだん狭くしていくといいらしい。文字間の無音は長点と同じ長さしかないので、聴いてみると案外短い。1文字ずつシーケンシャルに聴きとっていると間に合わないので、脳内でバッファリングしながら解読する必要がある。

覚える順番は LCWO.net準拠にしてある。LCWO.net もブラウザでモールス練習できるサイトで便利。グラフ化もしてくれるので、学習成果をテストするのに使ってた。ただ、mp3 をいちいちダウンロードしてくる感じなので、そのへんがちょっと使いにくい。コッホ法一通り終わって (20wpm 90%) からは Code Group のほうで 24wpm ぐらいまでちょくちょくテストしてたけど、最近はランダムじゃなくて意味のある単語の練習をしているので、やってない。

もう1年ぐらい前に作ったやつだけど日記にしていなかった。

  1. トップ
  2. tech
  3. ブラウザでモールス練習
  1. トップ
  2. ham
  3. ブラウザでモールス練習

『生還』 live at NHKホール 2013/05/08 [Blu-ray] - 五十嵐隆

五十嵐隆

5.0 / 5.0

非常に良かった。とりあえず中畑氏が最後のほう笑いながらたいこ叩いてたのが印象的だった。あと後光挿してる感じのライティングされていて笑った。

というのを作った。404 Not Found というのがあって、フィードをとってきてモールスにして再生するというもので、面白いのだけれど Java だし Mac だと音がおかしく試すのも辛い感じだった。簡単そうなので似たようなのを作った。

WebAudio + JavaScript のみで実装しているので、殆ど面倒なところはなく、Chrome for Android でも動くので外でも使える。

ただ、フィード取得に Yahoo! Pipes を使っていて、ときどき内容がとれないことがある。よくわからない。

しかし作ってちょっと聴いてみたけどさっぱり聴きとれない。多少は聴けるようになったかな〜と思ったけど全然だった。聴きとり全く上達しない。

  1. トップ
  2. tech
  3. モールスでニュースを聴く
  1. トップ
  2. ham
  3. モールスでニュースを聴く

会社用の名刺をあんまり持ち歩きたくないのと、今は基本的に勤務先を明らかにしない方針にしており、個人用のいい感じの名刺が欲しかったので作った。まぁ実際使うことは殆どないし、ただ今名刺切らしてメソッドで十分なんだけれども、作りたい欲が出たら作らなければならない。

久しぶりにイラレ使ったけど意外と操作覚えててよかった。

片面カラー・片面モノクロの100枚、角丸加工、送料など含めてオンデマンド印刷の業者で1400円ぐらいだったので安い。思ったよりできあがりも良くて楽しい感じだった。使わないけどいっぱい作りたくなる。

表は名前とURLが入ってるけど、裏は全面モノクロの写真にしてある。なんとなく裏にしてちょっと飾っておけるカードにしたくてそうしたけど、嬉しいの自分だけのやつだ。カット加工ができるならそのまま机における感じにしたいけどむずそう。

裏はこんな感じ