diff options
| author | nsfisis <nsfisis@gmail.com> | 2023-03-15 01:36:13 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-15 01:36:58 +0900 |
| commit | 98682c7a8792e7e79e487fea5024d25cee5aa310 (patch) | |
| tree | fbf975077f5c1a6ff4f9eee68e4a4908eb7f54a0 /public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3 | |
| parent | 1fa2ed103dc521698cff261c97ecf275708be58c (diff) | |
| download | blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.gz blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.zst blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.zip | |
fix(nuldoc): <pre> contained unnecessary whitespaces inside it
Diffstat (limited to 'public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3')
| -rw-r--r-- | public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html b/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html index 3100b8e..81d673f 100644 --- a/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html +++ b/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html @@ -82,8 +82,7 @@ 注意: これはボツ問なので、得られたトークンを PHPerKaigi で入力してもポイントにはならない。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php try { f(g() / __LINE__); } catch (Throwable $e) { @@ -194,8 +193,7 @@ function g() { return __LINE__; - }</code> - </pre> + }</code></pre> <p> "Catchline" と名付けた作品。実行するとトークン<code>#base64_decode('SGVsbG8sIFdvcmxkIQ==')</code>が得られる。 @@ -239,8 +237,7 @@ このうち 1つ目のケースは、<code>finally</code>節の中でエラーを投げると PHP 処理系が勝手に<code>$previous</code>を設定してくれる。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php try { try { @@ -253,8 +250,7 @@ // => Error 2 echo $e->getPrevious()->getMessage() . PHP_EOL; // => Error 1 - }</code> - </pre> + }</code></pre> <p> この知識を元に、トークンの出力部を解析してみる。 @@ -267,8 +263,7 @@ 出力部をコメントや改行を追加して再掲する: </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php try { f(g() / __LINE__); } catch (Throwable $e) { @@ -276,8 +271,7 @@ printf('%c', $e->getLine() + 23); } echo "\n"; - }</code> - </pre> + }</code></pre> <p> 出力をおこなう<code>catch</code>節を見てみると、<code>Throwable::getPrevious()</code>を呼び出してエラーチェインを辿り、<code>Throwable::getLine()</code>でエラーが発生した行数を取得している。その行数に<code>23</code>なるマジックナンバーを足し、フォーマット指定子<code>%c</code>で出力している。 @@ -287,9 +281,7 @@ フォーマット指定子<code>%c</code>は、整数を ASCII コード<span></span>と見做して印字する。トークン<code>#base64_decode('SGVsbG8sIFdvcmxkIQ==')</code>の<code>b</code>であれば、ASCII コード<code>98</code>なので、75 行目で発生したエラー、 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code> 1, 20 => 0 / 0,</code> - </pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code> 1, 20 => 0 / 0,</code></pre> <p> によって表現されている。エラーを起こす方法はいろいろと考えられるが、今回はゼロ除算を使った。 @@ -306,8 +298,7 @@ <code>f()</code>の定義を再掲する (エラーオブジェクトの行数を利用しているので、一部分だけ抜き出すと値が変わることに注意): </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code>function f(int $i) { + <pre class="highlight" language="php" linenumbering="unnumbered"><code>function f(int $i) { if ($i < 0) f(); try { match ($i) { @@ -326,24 +317,19 @@ } finally { f($i - 1); } - }</code> - </pre> + }</code></pre> <p> 前述のように、<code>finally</code>節でエラーを投げると PHP 処理系が<code>$previous</code>を設定する。ここでは、エラーを繋げるために<code>f()</code>を再帰呼び出ししている。最初に<code>f()</code>を呼び出している箇所を確認すると、 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php try { - f(g() / __LINE__); // 3 行目</code> - </pre> + f(g() / __LINE__); // 3 行目</code></pre> - <pre class="highlight" language="php" linenumbering="unnumbered"> - <code>function g() { + <pre class="highlight" language="php" linenumbering="unnumbered"><code>function g() { return __LINE__; // 111 行目 - }</code> - </pre> + }</code></pre> <p> <code>f()</code>には<code>111 / 3</code>で<code>37</code>が渡されることがわかる。そこから 1 ずつ減らして再帰呼び出ししていき、0 より小さくなったら<code>f()</code>を引数なしで呼び出す。引数の数が足りないと呼び出しに失敗するので、再帰はここで止まる。 |
