嘘つきPHP ZipArchive::addGlobと壊れたファイルパス

こんにちは.
KMC5回生のtyageです.

この記事は, KMCアドベントカレンダー 5日目の記事です.
昨日はnonyleneさんの Android Studio をビルドする でした.

唐突ですが, 今日はPHPの話をします.

TL;DR

PHPのZipArchiveライブラリには, globパターンでファイルを追加する addGlob メソッドがある.
これにはいくつかoptionが指定できるのだが, 挙動がおかしい.
送った修正PRに反応をもらえたため, 12/1にリリースされた PHP 7.1 に含まれないかなと期待していたが, 特に進展はなかった.
みんな困ってないんか…?

ZipArchive::addGlob

PHPでオシゴトをしていると, PHPでZipファイルを作りたい瞬間があるのではないかと思います.
私も, リクエスト内容が書かれたjsonファイルや画像をZipファイルでまとめてPOSTする超コズミックなAPIを叩く, 最高の機会がありました. (社会の歯車である一労働者は, 用意されたAPIに文句を言う前に黙々と作業をしなければいけない時があります.)
また, 様々な都合でZip圧縮前のフォルダを残しておく必要があったため, こんなコードを書いたのです.

$dir = '/tmp/workdir/';
 
// create jsons/api.json
$jsonDir = $dir . 'jsons';
mkdir($jsonDir);
file_put_contents($jsonDir. 'api.json', json_encode($request));
 
// create archive.zip
$zip = new ZipArchive();
$zip->open($dir . 'archive.zip', ZipArchive::CREATE);
$zip->addGlob($dir . '**/**', 0, ['remove_path' => $dir]);
$zip->close();

ZipArchive::addGlobは, 第一引数にファイル検索パターンを, 第二引数にglobのフラグを, 第三引数にその他optionを指定します.
このoptionが今回の焦点となるのですが, 以下の項目が設定できます.

オプションの連想配列。次のオプションが使えます。

  • “add_path”

    アーカイブ内のファイルのローカルパスに変換するときにつけるプレフィックス。
    これが適用されるのは、
    “remove_path”“remove_all_path”
    で定義された削除処理がすべて終わった後です。

  • “remove_path”

    マッチしたファイルをアーカイブに追加する前に削除するプレフィックス。

  • “remove_all_path”

    TRUE にすると、ファイル名だけを使ってアーカイブのルートに追加します。

ref: http://php.net/manual/ja/ziparchive.addglob.php

ふむふむ.

今回は remove_path を指定しており, 期待していた挙動としては,

  1. archive.zip というファイルができる
  2. そこには jsons/api.json というファイルが含まれている

です.

もし仮に, remove_path を指定していなければ /tmp/workdir/jsons/api.json というファイルが追加されるため, 正しくAPIを叩けなくなります.

で, 得られた結果がこれです.

/tmp/workdir ᐅ php -v
PHP 7.0.13 (cli) (built: Nov 15 2016 23:52:36) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

/tmp/workdir ᐅ unzip -l archive.zip
Archive:  archive.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        6  12-05-2016 18:04   /tmp/workdir/jsons/api.json
---------                     -------
        6                     1 file

あれ? remove_path optionを指定したのに /tmp/workdir/jsons/api.json のままですね…
どういうことでしょう?

問題1: add_path optionが必須

調べてみると, どうも add_path optionが有効でないと他のoptionが機能しないバグがあるようです.

issuePR はあるものの, まだマージされていませんでした.

仕方ないので, とりあえず add_path optionをつけて試してみることにします.

$zip->addGlob($dir . '**/**', 0, ['add_path' => 'prefix/', 'remove_path' => $dir]);

さて, この場合どうなるでしょうか?
/tmp/workdir/jsons/api.json から /tmp/workdir/ を削って, prefix/ を足すので prefix/jsons/api.json になりそうですね.
さて, 結果はというと…

/tmp/workdir ᐅ unzip -l archive.zip
Archive:  archive.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        6  12-05-2016 18:12   prefix/sons/api.json
---------                     -------
        6                     1 file

oh…
jsons の j がどこかに消えて prefix/sons/api.json になってしまいました.

問題2: 消えた j の謎

これは霊障でしょうか?
それとも宇宙線の影響でしょうか?

PHPソースコードを見ながら検証してみましょう.
addGlob でファイルを追加する場合は php_zip_add_from_pattern という関数を見ればよさそうです. (ext/zip/php_zip.c#L1618)

追加するファイルのファイルパスを操作しているのはここのようです.
remove_path_lenremove_path optionの文字数, zval_file は恐らく検索して見つかったファイルのファイルパスを指しているのでしょう.

1
2
3
4
5
6
7
8
9
10
11
12
if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(return_value), i)) != NULL) {
	if (remove_all_path) {
		basename = php_basename(Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), NULL, 0);
		file_stripped = ZSTR_VAL(basename);
		file_stripped_len = ZSTR_LEN(basename);
	} else if (remove_path && strstr(Z_STRVAL_P(zval_file), remove_path) != NULL) {
		file_stripped = Z_STRVAL_P(zval_file) + remove_path_len + 1;
		file_stripped_len = Z_STRLEN_P(zval_file) - remove_path_len - 1;
	} else {
		file_stripped = Z_STRVAL_P(zval_file);
		file_stripped_len = Z_STRLEN_P(zval_file);
	}

7行目を読んでみると, remove_path を指定した場合, ファイルパス指すポインタの指すアドレスが remove_path_len + 1 分進みます.
上の例であれば /tmp/workdir/j の文字数分進みます.

どうやらこれが原因みたいですね.
なんで + 1 されているのかさっぱりわからないのですが, まだバグ報告すらされていないようなので, とりあえずissueを立ててPRを送りましょう.

Bug #72374 ZipArchive::addGlob remove_path option strips first char of filename
Fix #72374: ZipArchive::addGlob remove_path option strips first char of filename #1939

2週間くらいで返事がもらえ, bugfixとして認識してもらえたようです.
ただ, Breaking ChangeなのでPHP7.1.0かPHP8にマージされそうです.(などと言っているうちに7.1.0がリリースされたのですが…)

PRを出してから半年が経過し, このままだと忘れ去られそうなのでここに記録することにしました.
早くマージされるといいなぁ.

既存のテストは?

ところで, remove_path optionに対するテストがなかったかというと, 実はありました.
ext/zip/tests/oo_addpattern.phpt

こんなコードでテストしています.

$dir = realpath($dirname);
$options = array('add_path' => 'baz/', 'remove_path' => $dir);
if (!$zip->addPattern('/\.txt$/', $dir, $options)) {
        echo "failed\n";
}

ここで, $dirname = "/tmp/workdir/"; であれば, $dir == "/tmp/workdir" になります.
ということは /tmp/workdir/hoge.txt から /tmp/workdir を削って baz/ を先頭に足すoptionになるわけですが, 上記のバグから baz//hoge.txt ではなく baz/hoge.txt が生成されます.
おめでたいテストですね.
これも修正対象です.

終わりに

問題の原因は見つかり解決策も出したのですが, まだマージされていません.
自前ビルドのPHPを運用するのも厳しいです.
結局, working directoryを移動して, remove_path optionを利用しない方向で解決しました.

$dir = '/tmp/workdir/';
chdir($dir); // change working dir!
 
// create jsons/api.json
$jsonDir = 'jsons';
mkdir($jsonDir);
file_put_contents($jsonDir. 'api.json', json_encode($request));
 
// create archive.zip
$zip = new ZipArchive();
$zip->open('archive.zip', ZipArchive::CREATE);
$zip->addGlob('**/**');
$zip->close();

もし同じ問題を抱えている人がいれば, この記事が救いになりますように…

明日は dnek_ さんの「1年間の進捗」です.

:visitedセレクタのプライバシー問題とSNSでの利用

追記(2015年9月9日)

以下の記事は、2015年1月4日時点での内容となります。

2015年9月9日時点において、IE11で:visitedなリンクに対して透過度を変更できる仕様は修正されているようです。

参考: CVE-2015-1765, Internet Explorer 用の累積的なセキュリティ更新プログラム (3058515)

:visitedセレクタについて

半年以上前に少し調べたことについてまとめてみたいと思います。

まずCSSの擬似セレクタに:visitedがあり、:visitedセレクタではプライバシーの問題上、使用可能なプロパティが制限されていることはご存知の方も多いと思います。

訪問済みリンクの要素にbackground-imageを設定することで、訪問済みリンクの情報が漏れるという問題等の対策です。
(Calm brilliance – CSS Fingerprint: preliminary data)

詳細は Privacy and the :visited selector にある通りですが、そこでは

You will still be able to visually style visited links, but there are now limits on what styles you can use. Only the following properties can be applied to visited links:

– color
– background-color
– border-color (and its sub-properties)
– outline-color
– The color parts of the fill and stroke properties

In addition, even for the properties you can set for visited links, you won’t be able to change the transparency between unvisited and visited links, as you otherwise would be able to using rgba() or hsla() color values or the transparent keyword.

とあります。

CSS Fingerprint対策の他に、レンダリング速度で差が出ることで訪問済みかどうか判断できないようにRGB値以外のものは変化しないようになっています。(透過度も不可)

またJavaScriptでも訪問済みサイトを判定できないようにするため、getComputedStyleでstyleを取得した際は非訪問時のstyleが返るようになっています。

各ブラウザでの実装

ただし上記はMozillaの方針でして、他ブラウザでの実装はそれによりまちまちのようです。

W3Cのほうでは以下の様な記述はありますが、具体的な内容については見つかりませんでした。)

UAs may therefore treat all links as unvisited links, or implement other measures to preserve the user’s privacy while rendering visited and unvisited links differently.

試しに http://jsfiddle.net/tyage/fhrojfdn/ を表示させてみました。


Google Chrome (39.0.2171.95)

スクリーンショット 2015-01-02 16.17.33

Firefox (33.1.1)

スクリーンショット 2015-01-02 16.18.41

Safari (8.0.2)

スクリーンショット 2015-01-02 16.20.18

Internet Explorer (11.0.7)

スクリーンショット 2015-01-02 16.20.46


上が:visitedで透過度を変化させた場合、下が色だけを変化させた場合です。

おっと。IEでは:visitedで透過度を変化させることができるようです。

Chromeではなぜかアンダーラインだけ適用されています。

これによって描画にかかる時間の差から、訪問済みか訪問済みでないかが分かる可能性がありますが、うまくテストできなかったのでスキップします…

Twitter IDの表示

透過度を変化させ、SNSのIDを表示することを考えてみました。

Twitterを例に出すと、https://analytics.twitter.com にアクセスした場合 https://analytics.twitter.com/user/[id]/tweets にリダイレクトされます。

これを利用して、https://analytics.twitter.com/user/aaa/tweets から https://analytics.twitter.com/user/zzz/tweets までのリンクを全て重ねて表示するページを作ってみます。
(訪問済みリンク以外はtransparentになるCSSを利用するため、IEのみで動作します)

http://jsfiddle.net/tyage/dtna2qsg/

上記URLではTwitter IDが3文字の場合のリンクしか表示しないので多くの方は何も表示されないかと思いますが、5文字まで表示したところ以下のように私のTwitter IDが表示されました。

スクリーンショット 2015-01-02 18.51.30

表示されたIDを自動的に取得することはできませんが、Captchaと称してユーザに入力させれば取得することができそうです。(この場合、表示する内容はIDではなくてもよいですね)

5文字の半角英数字(小文字)IDを全て表示すると 36^5 = 60466176 個となるので現実的ではありませんが、4文字程度ならギリギリ表示できるのではないでしょうか。

IE以外でも

先ほどの例はIEで透過度を変更可能であることを利用したものでしたが、それ以外のブラウザでも利用できるものを考えてみます。

Twitter以外のサービスでいうと、pixivが利用できるでしょうか。

pixivでは http://www.pixiv.net/mypage.php にアクセスすると http://www.pixiv.net/mypage.php#id=[id] へとリダイレクトされます。

これを利用して以下のページを作ってみました。

http://jsfiddle.net/tyage/vwdxysmf/

このページではpixiv idから適当な4桁の数字を引いたものを入力することが求められるのですが、そのIDからID+9999までのリンクを表示するようになっています。

unvisitedなページは黄色い四角で、visitedなページは赤い四角で出力され、赤い四角をクリックするとpixiv idが表示されます。

background-colorを変えているだけなのでChromeやFirefoxでも動作します。

10万程度までなら難なくリンクを描画できるのですが、ユーザに選択させるのが難しくなりそうです。(今回は10000個表示しています。)

まとめ

IEでは:visited要素に対しても透過度を変化させることができるようでした。

パフォーマンステストによる訪問済みリンクの検出は今後の課題としします。

今回はSNSのIDの取得について考えてみましたが、「ID数が膨大であるため現実的な速度でページを表示できない」、「表示された内容の取得に際してユーザの操作を必要とする」といった理由からあまり現実的な方法は見つかりませんでした。

ただし、表示するリンクが数万程度で済む場合は現実的な手段があるかもしれません。
(また訪問者が「100個のWebサービスのうちどれを利用しているユーザか」程度なら問題なく表示できそうです。)

表示された内容の取得に関しては、偽物のCaptchaを取り上げましたが、他にもゲームの操作で取得する方法もあるかと思います。

今のところこれを利用した実際の情報漏洩は起こっていないと思いますが(【要出典】)、ブラウザの更新で似たような穴が生まれる可能性もあるので気にしておきたい点ではあります。

録画環境を構築した

環境

ハードはこれ

OSは未だにUbuntu 12.04

録画するまで

ここ数カ月はサラリーマン生活をしていて、朝10時に出勤しているのだけど、そうなるとさすがに夜更しがつらくなってきた。

深夜アニメを見る生活も捨てがたいし録画することにした。

PCで見たいので録画カードとしてPT3を買った。

届いてから設置して、Ubuntuにドライバを入れたりした。

PT3のドライバがgithubにあったので、すごい時代だなあと思いながらインストール。

recpt1が必要とのことだったのでこことかを参考にぐぐりながら入れて、再起動。

B-CASカードに関してはここでは述べないこととする。

録画管理にはepgdumpではなく、chinachuを使うことにした。

たまたま冬コミでマニュアルを手に入れていたこともあるけど、モダンな感じなのとnode.jsで書かれているのがいい感じ。
(epgdumpも入れてみたけどapacheやmysql依存してると開発環境とぶつかってよくない感じに・・・)

chinachuのWUIは結構充実してて、その場で番組視聴したり録画視聴できるのが嬉しい。

node.jsは既に入っていたし、wikiに書いてあるとおりにやったらすんなりいけた。

コマンド1回でだいたい終わるのはとても気持ちいい。

設定に関して、チャンネルは下のように総当たりでスキャンするか地域で調べるかすればよさげ。

for var in `seq 13 80` ; do recpt1 --b25 --strip $var 10 ./$var.ts;done

ど素人だけど半日あれば十分だった。

エンコード問題

録画環境が構築できたので試しに録画してみた。

ある程度覚悟はしていたものの、30分のアニメでm2ts形式のファイルだと3GB前後といった感じだった。

うう〜ん。。。でかい。。。

とりあえずmp4に変換しようと思い、HandBrakeを使ってみる。

Linux環境でもQSVが使えるらしく、ffmpegよりエンコード速度が速いかもとのこと。

[追記: 2014/10/25]まだLinux環境でもサポートされていないようでした。

インストール時に注意なのが、「ppa:stebbins/handbrake-releases」には「handbrake」はなくて「handbrake-cli」と「handbrake-gtk」があるということ。

試しに比較してみると、30分のアニメで、HandBrakeだと20分、ffmpegだと60分以上かかった。

この時の圧縮後の容量はHandBrakeは400MB、ffmpegは600MBという感じだった。

HandBrakeのほうが画質が落ちているように見えるが、比較しなければ気にならない程度。

当然、エンコード方式等々で変わってくるだろうからコマンドを貼っておく。

ffmpeg -i in.m2ts -vcodec libx264 out.mp4
HandBrakeCLI -e x264 --deinterlace fast --h264-profile main --modulus 2 -q 22 --aencoder copy:aac -i in.m2ts -o out.mp4

適当にencodeしたので適切に圧縮されているのか少し不安である。

tssplitter_liteを使ってみたけど、髪の毛ほどしか変わらなかった。
(recpt1にtssplitter_liteが内臓されているらしいので、既に処理されていたのかも)

このまま1ファイル約400MBで保存したとすると、1クール過ぎるたびに 30番組 * 12本 * 400MB = 144GB の容量が必要になる。

実際どんな感じなんでしょうかみなさん。

今後したいこと

  • エンコード自動化(早く)
  • Twitter連携
  • 動画用ストレージの用意
  • 動画配信サーバの用意
  • 録画専用サーバの用意(余裕があれば)

まだ導入したてなので、エンコード自動化するスクリプト書いてない。

そもそもどんな感じにエンコードしたらいいのか見極めきれてない。

chinachuとの連携に関しても、普通はWebSocketで監視すればいいのだろうけど、録画完了したら勝手にスクリプト叩くようにいじったほうが楽そうでもあるし、少し考え中。

あとはCMを消すかどうか。

どうでもいい番組に関しては(間違って内容消されても痛くないので)消すかもしれない。

スペインでFirefox OS端末は買えるのか?

この記事はKMCアドベントカレンダーの4日目の記事です。

1〜3日目の人達は技術系の記事を書いているため、僕は少し緩めの話をしようと思います。

僕は10月末〜11月初めまで、Facebook CTF決勝のためにチームEpsilonDeltaの4人でスペインにいました。
その時に、スペインで販売されているFirefox OS搭載の端末「ZTE Open」を購入しようとしたという話です。

もし今後スペインに行くことがあり、携帯端末を購入するという方の参考になればと思います。

※Facebook CTFに関する詳しい内容はC85で頒布する部誌に記事を載せているのでそちらをよろしくお願いします。
3日目 西地区 ”し” ブロック 42bです。
よろしくお願いします。
3日目 西地区 ”し” ブロック 42bです。

事の始まり

Firefox OS搭載の端末は、先ほど出てきたZTE Openの他にもPeak・Peak+・Keonなどありますが、これらは既に品切れ状態が続いており(Peakは再生産するらしい?)ほとんど手に入らないようです。

ZTE Openが初めて販売されたのはスペインからということで少し話題になりました。(http://gigazine.net/news/20130710-firefox-os-smartphone-zte-open/)
ZTE Openはebayで輸入することができるため日本にいても手に入るのですが、輸入にかかる費用を含めて1万円弱($94.99 USD)かかります。
一方、スペインで買うと7000円弱(49 EUR)で手に入るとわかりました(運が良ければ中古で安く手に入らないかとも期待していた)。

せっかくスペインに行くのだしこれを自分へのおみやげにしようと決めて出発したのでした。

11/3 朝

スペイン・バルセロナ自体には10/30昼〜11/4昼までいたのですが、CTFがあったりその他に行く場所があったりして、ZTE Openを探す時間ができたのは11/3と11/4になってしまいました。

11/3も観光地に寄る予定を組んでいたために、朝に1時間ほどしか動けませんでした。

しかもこの日は日曜日。
スペインでは日曜日になるとほぼ全ての店が閉まってしまいます。(日本だと異常事態ですね。)

ということでこの日はどこに行っても閉店・・・(流石に一部のコンビニや観光地のショップは開いていましたが)
ホテル付近の店は全滅という状態で諦めざるを得ませんでした。

スペインに行く際は日曜日(domingo)に気をつけて下さい。

11/4 9:30

この日は最終日なので9:30-12:00までの間に急いで探さないと行けませんでした。

前日に調べた結果、とりあえずホテルのすぐ近くにあるmovistar直営店に寄ることにしました。

movistarというのはスペイン語圏の国々で主に活動している会社で、スペインで最大の携帯事業会社となっています。
世界第5位の通信事業会社Telefónicaの子会社でもあります。

スペイン最大ということもあって、バルセロナの町の至る所にmovistarの直営店がありました。
(その他にはvodafoneやorangeやyoigoといった会社が多く見られました。)

どこにmovistarがあるのかはこのページで確認することができるのですが、本当にバルセロナを埋め尽くしているという感じです。

スペインではこのmovistarがZTE Openを取り扱っているらしく、実際に店頭に並べられていたり広告が貼られているのは事前に確認済みです。
このような特設ページも作られています。
http://www.movistar.es/firefoxos

スペイン語がわからない人間のために英語で書かれたZTE Open購入マニュアルも見つけました。
How to Buy ZTE Open – Step by Step Guide

これで準備も万全だ!と満を持してmovistarに入ると、スペイン人のお姉ちゃんが1人で店番をしているだけでした。

僕「Hola!」
店員「Hola!」
僕「Is there ZTE Open in this shop?」
店「Ah… what?」
僕「uhm… Do you have any Z T E O p e n?」(手にZTE Openの文字を書きながら)
店「&#'(“#$%&'(`*@{}*」(スペイン語)
僕「P…Perdon?」
店「There is ZTE Open but It is locked so…」
僕「???」

みたいなやりとりを数分繰り返していたのですが、店員の話によると「movistarで販売されいてるZTE Openはsim lock freeではない」「MEDIAMARKTか近くのデパートの電気屋に行けば買えるかもしれない」ということでした。

MEDIAMARKTはドイツに本社があるヨーロッパ最大のマーケットのことで、バルセロナ市内にもあったのですが、1時間ほどかかる場所にあったため時間的に行けそうにありませんでした。

そこで先ほど店員に教えてもらった近くのデパートに向かうことにしました。

11/4 10:30

デパートの6階にmovistarやその他の携帯事業者の出す携帯端末の販売店がありました。

Samsung GalaxyやNexusやHTCといった日本でもよく見る端末の他に、名前を聞いたことがない端末がいくつか並んでいました。
知らない端末に購買欲を駆られましたが、今狙っている端末はただ1つZTE Openだけだと我慢することに。

とりあえず店員に英語で大丈夫かと話しかけたところ英語が話せない人だったため、英語のわかる店員を呼んでもらいました。
ZTE Openがあるかどうか、先ほどと同じ手段で聞いてみたのですが「そんなものは聞いたことがない、うちには置いてない」と言われ、諦めることにしました。

後々考えるとうまく伝わってない可能性があったので、ZTE Openのビラでも見せていれば実はここで買えていたかもしれません。

11/4 11:00

こうなってしまうとどこにも行くあてがないので、ぶらぶらと放浪しながらmovistarの別の店に寄ったりしていたのですが、たまたま行き着いた場所で「Phone House」という店を発見。
google mapsで検索をかけると他にも10分圏内の位置に何件かあることがわかったため、3件ほど訪れてみました。

中には端末がいくつか用意されており、どうやらSIMカードも買えるみたいでした。

しかし使える携帯事業者にvodafone・orange・yoigoはあるのですがmovistarがない。。。

恐る恐るZTE Openがあるかどうか聞いてみたのですが、「そんな端末聞いたことがないよ」と言われてしまいました。
今回はZTE Openと書いた紙を持っていったので、僕の発音がめちゃくちゃで聞き取れないというわけでもなさそうです。(以外と知名度が低い???)

後から調べたところPhone HouseではZTE Openは扱っていないようでした。
http://www.phonehouse.es/moviles?movil-marca=ZTE&movil-sistema=Android&movil-precio=#movil

とはいえPhone House、スペインでモバイル通信するにはとても便利そうです。

結局

今回の旅ではZTE Openを購入することはできませんでした。

で、どうしたかというとやっぱり諦めきれないため、知り合いとebayで共同購入することになりました。
共同購入すると少し安くなるらしい。

反省点としては事前調査と当日の活動時間が足りなかったかなあと思います。

ただスペインに行く前は「スペイン人は英語しゃべれないから気をつけたほうがいい」と聞かされており、確かにデパートの店員なんかは英語でコミュニケーションが取れなかったのですが、movistarやPhone Shopの店員は英語を聞き取れる方が多いので案外なんとかなるかと思います。
初めに英語で大丈夫か聞くと、恥ずかしそうに「A little.」とか言ってくれます。(かわいい)

明日はtsutchoさんによる「CUDAのメモリの種類が多くて面倒だという話」です。
お楽しみに。

最後に、movistarで見つけたFirefox OSのカタログや広告の画像を貼っておきます。

Untitled

Untitled

Untitled

Untitled

ところでこれ、Firefox OS Advent Calenderに載せたほうがよかったのでは・・・

何か吐き出さないとなあ

 
ここんところ某つぶやきサイトでうだうだ言ってるだけで、こうやって書くことがないからか、よくわからないストレスが溜まっている。
いろいろなことがあって(でも何もできてないのだけど)何か書かないといけないと思った。

とりあえず、以下のことについて書くつもりでいる。
・ウェブセキュリティ勉強会/OWASP Japan (大阪サテライト)
・会社でまた働き始めたこと
・情報セキュリティワークショップin越後湯沢
・アイデアソン
・SECCON CTF
・きょーくりっのワークショップ
・学校や、普段の生活のこと
・今まで一人でやっていたプロジェクトやプログラミングについて

こぼしたいことはあるはずなのに、なぜか手が進まないのでこうやって自分にプレッシャーをかけてみる。

自然とインプットもアウトプットもしなくなってから、自分が何をしているのかわからなくなったので振り返ればと思う。

ただ、NF(京大11月祭)も近いので、またどうなることやら・・・

google mapsでマーカーに文字を表示させたい

たとえばマーカーのアイコン画像の下に文字を表示したい。

こんな感じに

この画像ではマーカーの代わりにoverlayViewを継承したカスタムオーバーレイを使っている。

実際そうすれば問題はないんだけど、そうなるとMarkerClustererライブラリが使えない。

どうしても使いたい。
代わりになるものがあればそれでいいけど。。

あきらめてcanvasに文字を書いてdataスキームで画像として表示するとか・・・?