ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

limit nesting level of input variables(続き)

昨日のですが。
この件に関しては早めに対処した方が良いのかなぁ。。。とか思ってみたり。そうでもないのかしら。
とりあえず放流。っていうか、この程度のwarningは出さないようにして欲しいなぁ(main/php_variables.c:129: warning: int format, long int arg (arg 4))。
以下は、php-5.2.1からの差分(max_input_nesting_levelの機能を実装しただけ)。

--- php-5.2.1,orig/main/main.c	2007-01-08 12:39:09.000000000 +0900
+++ php-5.2.1/main/main.c	2007-03-08 12:16:12.038711906 +0900
@@ -304,6 +304,7 @@
 	STD_PHP_INI_ENTRY("upload_max_filesize",	"2M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			upload_max_filesize,	php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("post_max_size",			"8M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			post_max_size,			sapi_globals_struct,sapi_globals)
 	STD_PHP_INI_ENTRY("upload_tmp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	upload_tmp_dir,			php_core_globals,	core_globals)
+	STD_PHP_INI_ENTRY("max_input_nesting_level", "64",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLongGEZero,	max_input_nesting_level,			php_core_globals,	core_globals)
 
 	STD_PHP_INI_ENTRY("user_dir",				NULL,		PHP_INI_SYSTEM,		OnUpdateString,			user_dir,				php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("variables_order",		"EGPCS",	PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateStringUnempty,	variables_order,		php_core_globals,	core_globals)
--- php-5.2.1,orig/main/php_globals.h	2007-01-01 18:36:11.000000000 +0900
+++ php-5.2.1/main/php_globals.h	2007-03-08 12:16:12.237684665 +0900
@@ -155,6 +155,7 @@
 #ifdef PHP_WIN32
 	zend_bool com_initialized;
 #endif
+	long max_input_nesting_level;
 };
 
 
--- php-5.2.1,orig/main/php_variables.c	2007-01-21 07:16:24.000000000 +0900
+++ php-5.2.1/main/php_variables.c	2007-03-08 12:16:12.551641681 +0900
@@ -119,10 +119,16 @@
 	index_len = var_len;
 
 	if (is_array) {
+		int nest_level = 0;
 		while (1) {
 			char *index_s;
 			int new_idx_len = 0;
 
+			if(++nest_level > PG(max_input_nesting_level)) {
+				/* too many levels of nesting */
+				php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variable nesting level more than allowed %ld (change max_input_nesting_level in php.ini to increase the limit)", PG(max_input_nesting_level));
+			}
+
 			ip++;
 			index_s = ip;
 			if (isspace(*ip)) {

以下は、php-4.4.6からの差分(max_input_nesting_levelの機能を実装しただけ)。
微妙に構造がphp-5.2.1と違っていたのでフラグ初期化のタイミングに悩んだけど、軽く確認した限りでは正しく動いている模様。。。更なる動作の確認を希望。

--- php-4.4.6,orig/main/main.c	2007-01-01 18:46:50.000000000 +0900
+++ php-4.4.6/main/main.c	2007-03-08 19:50:50.867694169 +0900
@@ -338,6 +338,7 @@
 	STD_PHP_INI_ENTRY("upload_max_filesize",	"2M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateInt,			upload_max_filesize,	php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("post_max_size",			"8M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateInt,			post_max_size,			sapi_globals_struct,sapi_globals)
 	STD_PHP_INI_ENTRY("upload_tmp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	upload_tmp_dir,			php_core_globals,	core_globals)
+	STD_PHP_INI_ENTRY("max_input_nesting_level", "64",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLongGEZero,	max_input_nesting_level,			php_core_globals,	core_globals)
 
 	STD_PHP_INI_ENTRY("user_dir",				NULL,		PHP_INI_SYSTEM,		OnUpdateString,			user_dir,				php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("variables_order",		NULL,		PHP_INI_ALL,		OnUpdateStringUnempty,	variables_order,		php_core_globals,	core_globals)
--- php-4.4.6,orig/main/php_globals.h	2007-01-01 18:46:50.000000000 +0900
+++ php-4.4.6/main/php_globals.h	2007-03-08 19:50:51.097662674 +0900
@@ -91,6 +91,7 @@
 
 	char *upload_tmp_dir;
 	long upload_max_filesize;
+	long max_input_nesting_level;
 	
 	char *error_append_string;
 	char *error_prepend_string;
--- php-4.4.6,orig/main/php_variables.c	2007-01-01 18:46:50.000000000 +0900
+++ php-4.4.6/main/php_variables.c	2007-03-08 19:50:51.250641724 +0900
@@ -66,6 +66,7 @@
 	zval *gpc_element, **gpc_element_p;
 	zend_bool is_array;
 	HashTable *symtable1=NULL;
+	int nest_level = 0;
 
 	assert(var != NULL);
 	
@@ -128,6 +129,11 @@
 			char *escaped_index = NULL, *index_s;
 			int new_idx_len = 0;
 
+			if(++nest_level > PG(max_input_nesting_level)) {
+				/* too many levels of nesting */
+				php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variable nesting level more than allowed %ld (change max_input_nesting_level in php.ini to increase the limit)", PG(max_input_nesting_level));
+			}
+
 			ip++;
 			index_s = ip;
 			if (isspace(*ip)) {
@@ -184,6 +190,7 @@
 				*ip = 0;
 			} else {
 				is_array = 0;
+				nest_level = 0;
 			}
 		} else {
 plain_var:

以下は、php-5.2.1から5.2.2-dev(php5.2-200703080130)の差分。
なんか微妙に追加されていますね(php_shutdown_temporary_directory関数を呼び出している)。

--- php-5.2.1,orig/main/main.c	2007-01-08 12:39:09.000000000 +0900
+++ php5.2-200703080130/main/main.c	2007-03-03 08:30:56.000000000 +0900
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: main.c,v 1.640.2.23.2.29 2007/01/08 03:39:09 iliaa Exp $ */
+/* $Id: main.c,v 1.640.2.23.2.31 2007/03/02 21:58:05 stas Exp $ */
 
 /* {{{ includes
  */
@@ -83,6 +83,7 @@
 #include "php_ticks.h"
 #include "php_logos.h"
 #include "php_streams.h"
+#include "php_open_temporary_file.h"
 
 #include "SAPI.h"
 #include "rfc1867.h"
@@ -304,6 +305,7 @@
 	STD_PHP_INI_ENTRY("upload_max_filesize",	"2M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			upload_max_filesize,	php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("post_max_size",			"8M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLong,			post_max_size,			sapi_globals_struct,sapi_globals)
 	STD_PHP_INI_ENTRY("upload_tmp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	upload_tmp_dir,			php_core_globals,	core_globals)
+	STD_PHP_INI_ENTRY("max_input_nesting_level", "64",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateLongGEZero,	max_input_nesting_level,			php_core_globals,	core_globals)
 
 	STD_PHP_INI_ENTRY("user_dir",				NULL,		PHP_INI_SYSTEM,		OnUpdateString,			user_dir,				php_core_globals,	core_globals)
 	STD_PHP_INI_ENTRY("variables_order",		"EGPCS",	PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateStringUnempty,	variables_order,		php_core_globals,	core_globals)
@@ -1692,6 +1694,8 @@
 	ts_free_id(core_globals_id);	
 #endif
 
+	php_shutdown_temporary_directory();
+
 	module_initialized = 0;
 }
 /* }}} */
--- php-5.2.1,orig/main/php_globals.h	2007-01-01 18:36:11.000000000 +0900
+++ php5.2-200703080130/main/php_globals.h	2007-03-03 08:30:56.000000000 +0900
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_globals.h,v 1.98.2.1.2.4 2007/01/01 09:36:11 sebastian Exp $ */
+/* $Id: php_globals.h,v 1.98.2.1.2.5 2007/03/02 21:58:05 stas Exp $ */
 
 #ifndef PHP_GLOBALS_H
 #define PHP_GLOBALS_H
@@ -155,6 +155,7 @@
 #ifdef PHP_WIN32
 	zend_bool com_initialized;
 #endif
+	long max_input_nesting_level;
 };
 
 
--- php-5.2.1,orig/main/php_variables.c	2007-01-21 07:16:24.000000000 +0900
+++ php5.2-200703080130/main/php_variables.c	2007-03-03 08:30:56.000000000 +0900
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_variables.c,v 1.104.2.10.2.4 2007/01/20 22:16:24 iliaa Exp $ */
+/* $Id: php_variables.c,v 1.104.2.10.2.6 2007/03/02 22:03:05 stas Exp $ */
 
 #include <stdio.h>
 #include "php.h"
@@ -119,10 +119,16 @@
 	index_len = var_len;
 
 	if (is_array) {
+		int nest_level = 0;
 		while (1) {
 			char *index_s;
 			int new_idx_len = 0;
 
+			if(++nest_level > PG(max_input_nesting_level)) {
+				/* too many levels of nesting */
+				php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variable nesting level more than allowed %d (change max_input_nesting_level in php.ini to increase the limit)", PG(max_input_nesting_level));
+			}
+
 			ip++;
 			index_s = ip;
 			if (isspace(*ip)) {