[ポピュラーサイエンス記事] 弱い型の比較に関する PHP カーネルの動的デバッグ

WBOY
リリース: 2016-06-20 12:26:37
オリジナル
970 人が閲覧しました

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. のブログ

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート