KiSAKU
技術系約4分で読めます

どこが悪いかを、11回で突き止める — 本文を半分ずつ切る

公開

1500文字の本文のどこか1か所が、遮断の仕組みに引っかかっています。どこかは教えてもらえません。

読んで探すのは諦めました。代わりに、半分ずつ削って試す作業を11回やりました。

この記事で扱うこと

原因の場所を機械的に絞り込む手順。試行回数がどう減るか、確かめる作業をどう自動化したか、そして引き金が2つあると手順が嘘をつくという落とし穴です。

連載「弾かれる」(全5回)

第1回:症状の切り分け/第2回:二分探索で原因を絞る(この記事)/第3回:エスケープが効かなかった理由/第4回:意味を変えずに書き直す/第5回:正しく止められたときに何を残すか

読んで探すと、範囲が減らない

最初は目で探しました。怪しそうな行を眺めて、直して、投げる。落ちる。また眺める。

この方法の問題は、1回試しても候補が減らないことです。「これは違った」が1つ分かるだけで、残りは全部そのままです。

やり方 1回試すと
怪しい行を直す 候補が1つ減る
半分だけ送る 候補が半分になる

1500文字から1文字まで絞るのに、前者だと最悪1500回。後者なら11回です。

半分に切って投げる

手順は単純です。

手順 やること
1 本文の前半だけを送る
2 落ちたら、原因は前半にある。前半を新しい範囲にする
3 通ったら、原因は後半にある。後半を新しい範囲にする
4 範囲が1文字になるまで、1に戻る

実際の減り方はこうなりました。

回 残りの範囲
開始 1500文字
3回後 約190文字
6回後 約24文字
9回後 約3文字
11回後 1文字
半分にする作業は、内容を理解していなくてもできる

この手順のいいところは、何が悪いかを知らなくても進むことです。判断しているのは「落ちたか、通ったか」だけで、中身を読んでいません。

読んで探す方法は、自分が気づける範囲しか探せません。見慣れた書き方が原因だと、何度読んでも飛ばします。

試す作業を、1行で済むようにした

11回とはいえ、毎回やることがあります。下書きを作って、結果を見て、作られた下書きを消す。手でやると1回2分かかります。

そこで、ブラウザの中に確かめるための小さな仕組みを置きました。やっていることは3つだけです。

順番 やること
1 渡された文章で下書きを1つ作る
2 作れたら、その下書きをすぐ消す
3 作れたなら「通った」、断られたなら「落ちた」を返す

これで1回が数秒になりました。11回を苦にしないための準備が、結果としていちばん効いています。

試した跡を残さない

2番目の「すぐ消す」を入れていないと、11個の中途半端な下書きが残ります。

調べる作業は、調べた跡を片づけるところまでが手順です。途中で中断したときに散らかるのは、片づけを最後にまとめているからでした。

引き金が2つあると、手順が嘘をつく

ここで一度つまずきました。前半を送っても落ちる。後半を送っても落ちる。どちらにもあるということです。

半分に切る手順は、原因が1つだけという前提で動いています。2つあると、どちらへ進んでも落ちるので、絞り込みが止まります。

前半 後半 意味
落ちる 通る 原因は前半に1つ
通る 落ちる 原因は後半に1つ
落ちる 落ちる 両方にある。1つずつ片づける
通る 通る 切った境目にまたがっている

やったのは、前半だけで最後まで絞り切って、見つけた1つを取り除いてから、もう一度全体で始めることでした。2周目で2つめが出てきます。

4行目も起こる

両方通るのに全体だと落ちる場合もあります。切った位置が、原因のちょうど真ん中を通っているときです。

このときは切る位置を数文字ずらして、もう一度試します。「両方通る」は正常ではなく、切り方の問題です。

見つかったのは、2つの短い並び

結果として、引っかかっていたのはたった2種類の文字の並びでした。どちらもプログラムを書くうえではありふれた形です。

片方は、文字列を囲むために使う記号を対で使ったときだけ反応しました。1つだけなら通ります。もう片方は、ある命令の名前に括弧が続いた形です。引用符で囲んでも、囲まなくても落ちました。

どちらも、攻撃に使われる形と見分けがつきません。判定している側は正しく仕事をしています。こちらが普通のコードを書いているだけです。

今回の学び

まず、1回で候補が半分になる方法を選ぶということ。怪しい所を直す方法は、1回試しても候補が1つしか減りません。同じ11回で、1500文字から1文字まで届くかどうかが変わります。

次に、絞り込む作業は、中身を理解していなくても進むこと。判断材料は「通ったか落ちたか」だけでした。読んで探す方法は自分が気づける範囲しか探せないので、見慣れた書き方が原因だと永久に見つかりません。

そして、原因が1つという前提を疑うこと。両側とも落ちるのは手順の失敗ではなく、2つあるという情報です。片方を取り除いてからやり直すと進みました。

この記事を共有する

Xでポストはてブ
← ブログ一覧へ戻る