0x00 序文
前号の 3 つのホワイト ハット チャレンジの質問は終了しましたが、皆さんはまだ記事での知識ポイントについての議論に興味を持っています。これは PHP の弱い型に関するものです:
array(0)>999999999
この結果は true です。
グループの専門家はさまざまな考えと関連記事を提供しました:
php.net/manual/zh/ language.operators.comparison.php
しかし基本的にはすべて他人が出した結論は好きではありません。結果だけを教えてくれるので、なぜそのような結果になったのかは知りません。
0x01 php 動的デバッグ (例として php5.6)
1. ダウンロード、解凍、インストール
# wget http://cn2.php.net/distributions/php-5.6.0.tar.xz # xz -d php-5.6.0.tar.xz # tar vxf php-5.6.0.tar # cd php-5.6.0 # ./configure --enable-debug # make # sudo make install
2. おすすめ関連記事
「Zend 実行エンジン (PHP5) を深く理解する」
「vld を使用して OPCode を表示する」
「PHP ソースコードをデバッグする」
0x02 OPCode 解析
上記の推奨記事をよく読むと、キー操作が IS_SMALLER であることがわかります。 find the key function
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
0x03 gdb 動的デバッグ
赤枠内の内容に注目してください。上記の内容を読んだ人なら誰でも理解できると思います。 (追記: 詳細が多すぎるので、最初に推奨記事を読んでください)
一般的なロジックは、2 つのパラメーターが入力され、zendi_convert_scalar_to_number 関数によって処理されるというものです。配列、もう 1 つは整数です。2 つのパラメーターの型と値は変更されません。
#define zendi_convert_scalar_to_number(op, holder, result) if (op==result) { if (Z_TYPE_P(op) != IS_LONG) { convert_scalar_to_number(op TSRMLS_CC); } } else { switch (Z_TYPE_P(op)) { case IS_STRING: { if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { ZVAL_LONG(&(holder), 0); } (op) = &(holder); break; } case IS_BOOL: case IS_RESOURCE: ZVAL_LONG(&(holder), Z_LVAL_P(op)); (op) = &(holder); break; case IS_NULL: ZVAL_LONG(&(holder), 0); (op) = &(holder); break; case IS_OBJECT: (holder) = (*(op)); zval_copy_ctor(&(holder)); convert_to_long_base(&(holder), 10); if (Z_TYPE(holder) == IS_LONG) { (op) = &(holder); } break; } }
次に、ループに再度入って到着します。
} else if (Z_TYPE_P(op1)==IS_ARRAY) { ZVAL_LONG(result, 1); return SUCCESS; } else if (Z_TYPE_P(op2)==IS_ARRAY) { ZVAL_LONG(result, -1); return SUCCESS;
オペコードから、op2 がわかります。は array(0) なので、ここでは -1 が返されます
最終的に (Z_LVAL_P(result) < 0) が成立し、true が返されます
if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) { return FAILURE; } ZVAL_BOOL(result, (Z_LVAL_P(result) < 0)); return SUCCESS;
"[人気の科学記事] 弱い型の比較に関する PHP カーネルの動的デバッグ」 L.N. のブログ