stas Wed Sep 19 00:30:53 2007 UTC Modified files: (Branch: PHP_5_2) /php-src/ext/iconv iconv.c php_iconv.h Log: limit iconv parameter sizes - workaround for glibc bug
http://cvs.php.net/viewvc.cgi/php-src/ext/iconv/iconv.c?r1=1.124.2.8.2.16&r2=1.124.2.8.2.17&diff_format=u Index: php-src/ext/iconv/iconv.c diff -u php-src/ext/iconv/iconv.c:1.124.2.8.2.16 php-src/ext/iconv/iconv.c:1.124.2.8.2.17 --- php-src/ext/iconv/iconv.c:1.124.2.8.2.16 Sat May 19 17:52:30 2007 +++ php-src/ext/iconv/iconv.c Wed Sep 19 00:30:52 2007 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: iconv.c,v 1.124.2.8.2.16 2007/05/19 17:52:30 iliaa Exp $ */ +/* $Id: iconv.c,v 1.124.2.8.2.17 2007/09/19 00:30:52 stas Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -233,12 +233,21 @@ #define GENERIC_SUPERSET_NBYTES 4 /* }}} */ +static PHP_INI_MH(OnUpdateStringIconvCharset) +{ + if(new_value_length >= ICONV_CSNMAXLEN) { + return FAILURE; + } + OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + return SUCCESS; +} + /* {{{ PHP_INI */ PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("iconv.input_encoding", ICONV_INPUT_ENCODING, PHP_INI_ALL, OnUpdateString, input_encoding, zend_iconv_globals, iconv_globals) - STD_PHP_INI_ENTRY("iconv.output_encoding", ICONV_OUTPUT_ENCODING, PHP_INI_ALL, OnUpdateString, output_encoding, zend_iconv_globals, iconv_globals) - STD_PHP_INI_ENTRY("iconv.internal_encoding", ICONV_INTERNAL_ENCODING, PHP_INI_ALL, OnUpdateString, internal_encoding, zend_iconv_globals, iconv_globals) + STD_PHP_INI_ENTRY("iconv.input_encoding", ICONV_INPUT_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, input_encoding, zend_iconv_globals, iconv_globals) + STD_PHP_INI_ENTRY("iconv.output_encoding", ICONV_OUTPUT_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, output_encoding, zend_iconv_globals, iconv_globals) + STD_PHP_INI_ENTRY("iconv.internal_encoding", ICONV_INTERNAL_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, internal_encoding, zend_iconv_globals, iconv_globals) PHP_INI_END() /* }}} */ @@ -1858,7 +1867,7 @@ PHP_FUNCTION(iconv_strlen) { char *charset; - int charset_len; + int charset_len = 0; char *str; int str_len; @@ -1873,6 +1882,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + err = _php_iconv_strlen(&retval, str, str_len, charset); _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); if (err == PHP_ICONV_ERR_SUCCESS) { @@ -1888,7 +1902,7 @@ PHP_FUNCTION(iconv_substr) { char *charset; - int charset_len; + int charset_len = 0; char *str; int str_len; long offset, length; @@ -1905,6 +1919,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + if (ZEND_NUM_ARGS() < 3) { length = str_len; } @@ -1925,7 +1944,7 @@ PHP_FUNCTION(iconv_strpos) { char *charset; - int charset_len; + int charset_len = 0; char *haystk; int haystk_len; char *ndl; @@ -1945,6 +1964,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + if (offset < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); RETURN_FALSE; @@ -1971,7 +1995,7 @@ PHP_FUNCTION(iconv_strrpos) { char *charset; - int charset_len; + int charset_len = 0; char *haystk; int haystk_len; char *ndl; @@ -1993,6 +2017,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + err = _php_iconv_strpos(&retval, haystk, haystk_len, ndl, ndl_len, -1, charset); _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); @@ -2049,6 +2078,11 @@ } if (zend_hash_find(Z_ARRVAL_P(pref), "input-charset", sizeof("input-charset"), (void **)&ppval) == SUCCESS) { + if (Z_STRLEN_PP(ppval) >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { in_charset = Z_STRVAL_PP(ppval); } @@ -2056,6 +2090,11 @@ if (zend_hash_find(Z_ARRVAL_P(pref), "output-charset", sizeof("output-charset"), (void **)&ppval) == SUCCESS) { + if (Z_STRLEN_PP(ppval) >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { out_charset = Z_STRVAL_PP(ppval); } @@ -2120,7 +2159,7 @@ PHP_FUNCTION(iconv_mime_decode) { char *encoded_str; - int encoded_str_len; + int encoded_str_len = 0; char *charset; int charset_len; long mode = 0; @@ -2137,6 +2176,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + err = _php_iconv_mime_decode(&retval, encoded_str, encoded_str_len, charset, NULL, mode); _php_iconv_show_error(err, charset, "???" TSRMLS_CC); @@ -2160,7 +2204,7 @@ const char *encoded_str; int encoded_str_len; char *charset; - int charset_len; + int charset_len = 0; long mode = 0; php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; @@ -2173,6 +2217,11 @@ RETURN_FALSE; } + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + array_init(return_value); while (encoded_str_len > 0) { @@ -2255,13 +2304,18 @@ { char *in_charset, *out_charset, *in_buffer, *out_buffer; size_t out_len; - int in_charset_len, out_charset_len, in_buffer_len; + int in_charset_len = 0, out_charset_len = 0, in_buffer_len; php_iconv_err_t err; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &in_charset, &in_charset_len, &out_charset, &out_charset_len, &in_buffer, &in_buffer_len) == FAILURE) return; + if (in_charset_len >= ICONV_CSNMAXLEN || out_charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + err = php_iconv_string(in_buffer, (size_t)in_buffer_len, &out_buffer, &out_len, out_charset, in_charset); _php_iconv_show_error(err, out_charset, in_charset TSRMLS_CC); @@ -2330,11 +2384,16 @@ PHP_FUNCTION(iconv_set_encoding) { char *type, *charset; - int type_len, charset_len, retval; + int type_len, charset_len =0, retval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &type, &type_len, &charset, &charset_len) == FAILURE) return; + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + if(!strcasecmp("input_encoding", type)) { retval = zend_alter_ini_entry("iconv.input_encoding", sizeof("iconv.input_encoding"), charset, charset_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } else if(!strcasecmp("output_encoding", type)) { @@ -2726,6 +2785,10 @@ ++to_charset; to_charset_len = strlen(to_charset); + if (from_charset_len >= ICONV_CSNMAXLEN || to_charset_len >= ICONV_CSNMAXLEN) { + return NULL; + } + if (NULL == (inst = pemalloc(sizeof(php_iconv_stream_filter), persistent))) { return NULL; } http://cvs.php.net/viewvc.cgi/php-src/ext/iconv/php_iconv.h?r1=1.28.2.2.2.1&r2=1.28.2.2.2.2&diff_format=u Index: php-src/ext/iconv/php_iconv.h diff -u php-src/ext/iconv/php_iconv.h:1.28.2.2.2.1 php-src/ext/iconv/php_iconv.h:1.28.2.2.2.2 --- php-src/ext/iconv/php_iconv.h:1.28.2.2.2.1 Mon Jan 1 09:36:01 2007 +++ php-src/ext/iconv/php_iconv.h Wed Sep 19 00:30:52 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Revision: 1.28.2.2.2.1 $ */ +/* $Revision: 1.28.2.2.2.2 $ */ #ifndef PHP_ICONV_H #define PHP_ICONV_H @@ -79,6 +79,10 @@ #define ICONV_OUTPUT_ENCODING "ISO-8859-1" #define ICONV_INTERNAL_ENCODING "ISO-8859-1" +#ifndef ICONV_CSNMAXLEN +#define ICONV_CSNMAXLEN 64 +#endif + /* {{{ typedef enum php_iconv_err_t */ typedef enum _php_iconv_err_t { PHP_ICONV_ERR_SUCCESS = SUCCESS,
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php