mcryptの件の結末

昨日のエントリーの一件は各所の紳士の活躍により解決となりました。

現状ではマニュアルにあるような動作をしない状態になっている事は間違いないようです。
週末にバグレポートを出しておこうと思います。

今回はid:shimookaさんの迅速な調査のおかげで真相を知ることができました。
ありがとうございます。やっぱりエロい人はすごいです。

自分の調査で読み落としてしまった点が残念なのでもう一度振り返り。

if (Z_STRLEN_PP(key) == 0) {
	php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size is 0");
}

key_s = emalloc(Z_STRLEN_PP(key));
memset(key_s, 0, Z_STRLEN_PP(key));

iv_s = emalloc(iv_size + 1);
memset(iv_s, 0, iv_size + 1);

if (Z_STRLEN_PP(key) > max_key_size) {
	php_error_docref(NULL TSRMLS_CC, E_WARNING,
	"Key size too large; supplied length: %d, max: %d",
	 Z_STRLEN_PP(key), max_key_size);
	key_size = max_key_size;
} else {
	key_size = Z_STRLEN_PP(key);
}
memcpy(key_s, Z_STRVAL_PP(key), Z_STRLEN_PP(key));

if (Z_STRLEN_PP(iv) != iv_size) {
	php_error_docref(NULL TSRMLS_CC, E_WARNING,
	"Iv size incorrect; supplied length: %d, needed: %d",
	 Z_STRLEN_PP(iv), iv_size);
}
memcpy(iv_s, Z_STRVAL_PP(iv), iv_size);

mcrypt_generic_deinit(pm->td);
result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s);

/* If this function fails, close the mcrypt module to prevent crashes
 * when further functions want to access this resource */
if (result < 0) {
	zend_list_delete(Z_LVAL_PP(mcryptind));
	switch (result) {
		case -3:
			php_error_docref(NULL TSRMLS_CC, E_WARNING,
			 "Key length incorrect");
			break;
		case -4:
			php_error_docref(NULL TSRMLS_CC, E_WARNING,
			 "Memory allocation error");
			break;
		case -1:
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING,
			 "Unknown error");
			break;
	}
}
pm->init = 1;
RETVAL_LONG(result);

前回はこの内容の後半部分に目が行ってしまったんですが、そこより手前が問題でした。
実際に出力されていたエラーメッセージも

Warning: mcrypt_generic_init(): Key size too large; supplied length: 34, max: 32 
in /a/ndev01/usr/local/www/_PERSONAL/ts-yando/test/mcrypt.php on line 19

Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 3, needed: 32 
in /a/ndev01/usr/local/www/_PERSONAL/ts-yando/test/mcrypt.php on line 19
int(0)

php_error_docref で指定しているものですし、一目でわかりますね。

php_error_docref(NULL TSRMLS_CC, E_WARNING,"Key size too large; supplied length: %d, max: %d",
Z_STRLEN_PP(key), max_key_size);
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Iv size incorrect; supplied length: %d, needed: %d",
Z_STRLEN_PP(iv), iv_size);

cvs annによるとこの部分のコードは昨日今日に書かれたわけではないように見えます。

さかのぼっていってもphp_error_docref が sprintf + php_error だったり memcopy strncopy になってたりはする。
マニュアルはいつの時点の記述なのだろう・・・。
単にlibmcryptの仕様に基づいて書いてあったのかなとも思います。

今回は勉強になりました。id:shimookaさんid:masugataさん ありがとうございました。