From 8cdc2fec197d02fc91a686a33e69186bac8849ef Mon Sep 17 00:00:00 2001 From: Moriyoshi Koizumi Date: Wed, 23 Mar 2005 23:08:25 +0000 Subject: [PATCH] - MFH: Add sanity check in iconv_mime_encode(). Leaving the third parameter unspecified would yield bus error. - MFH: Add testcase for the bug. --- ext/iconv/iconv.c | 113 +++++++++++++++++----------------- ext/iconv/tests/iconv004.phpt | 10 +++ 2 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 ext/iconv/tests/iconv004.phpt diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index ae03c705bf..b8c76c5bed 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1909,24 +1909,20 @@ PHP_FUNCTION(iconv_strrpos) Composes a mime header field with field_name and field_value in a specified scheme */ PHP_FUNCTION(iconv_mime_encode) { - char *field_name; + const char *field_name = NULL; int field_name_len; - char *field_value; + const char *field_value = NULL; int field_value_len; - zval *pref; - zval val, *pval, **ppval; - char *in_charset; - char *out_charset; - long line_len = 76; - zval lfchars; - - php_iconv_enc_scheme_t scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; - + zval *pref = NULL; + zval tmp_zv, *tmp_zv_p = NULL; smart_str retval = {0}; - php_iconv_err_t err; - in_charset = ICONVG(internal_encoding); + const char *in_charset = ICONVG(internal_encoding); + const char *out_charset = in_charset; + long line_len = 76; + const char *lfchars = "\r\n"; + php_iconv_enc_scheme_t scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a", &field_name, &field_name_len, &field_value, &field_value_len, @@ -1935,65 +1931,70 @@ PHP_FUNCTION(iconv_mime_encode) RETURN_FALSE; } - if (zend_hash_find(Z_ARRVAL_P(pref), "scheme", sizeof("scheme"), (void **)&ppval) == SUCCESS) { - if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { - switch (Z_STRVAL_PP(ppval)[0]) { - case 'B': case 'b': - scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; - break; + if (pref != NULL) { + zval **ppval; - case 'Q': case 'q': - scheme_id = PHP_ICONV_ENC_SCHEME_QPRINT; - break; + if (zend_hash_find(Z_ARRVAL_P(pref), "scheme", sizeof("scheme"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + switch (Z_STRVAL_PP(ppval)[0]) { + case 'B': case 'b': + scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; + break; + + case 'Q': case 'q': + scheme_id = PHP_ICONV_ENC_SCHEME_QPRINT; + break; + } } } - } - - in_charset = ICONVG(internal_encoding); - if (zend_hash_find(Z_ARRVAL_P(pref), "input-charset", sizeof("input-charset"), (void **)&ppval) == SUCCESS) { - if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { - in_charset = Z_STRVAL_PP(ppval); + if (zend_hash_find(Z_ARRVAL_P(pref), "input-charset", sizeof("input-charset"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + in_charset = Z_STRVAL_PP(ppval); + } } - } - out_charset = in_charset; - if (zend_hash_find(Z_ARRVAL_P(pref), "output-charset", sizeof("output-charset"), (void **)&ppval) == SUCCESS) { - if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { - out_charset = Z_STRVAL_PP(ppval); + if (zend_hash_find(Z_ARRVAL_P(pref), "output-charset", sizeof("output-charset"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + out_charset = Z_STRVAL_PP(ppval); + } } - } - if (zend_hash_find(Z_ARRVAL_P(pref), "line-length", sizeof("line-length"), (void **)&ppval) == SUCCESS) { - pval = *ppval; - if (Z_TYPE_P(pval) != IS_LONG) { - val = *pval; - zval_copy_ctor(&val); - convert_to_long(&val); - pval = &val; - } + if (zend_hash_find(Z_ARRVAL_P(pref), "line-length", sizeof("line-length"), (void **)&ppval) == SUCCESS) { + zval val, *pval = *ppval; + + if (Z_TYPE_P(pval) != IS_LONG) { + val = *pval; + zval_copy_ctor(&val); + convert_to_long(&val); + pval = &val; + } - line_len = Z_LVAL_P(pval); + line_len = Z_LVAL_P(pval); - if (pval == &val) { - zval_dtor(&val); + if (pval == &val) { + zval_dtor(&val); + } } - } - if (zend_hash_find(Z_ARRVAL_P(pref), "line-break-chars", sizeof("line-break-chars"), (void **)&ppval) == SUCCESS) { - lfchars = **ppval; - zval_copy_ctor(&lfchars); + if (zend_hash_find(Z_ARRVAL_P(pref), "line-break-chars", sizeof("line-break-chars"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) != IS_STRING) { + tmp_zv = **ppval; + zval_copy_ctor(&tmp_zv); + convert_to_string(&tmp_zv); - if (Z_TYPE(lfchars) != IS_STRING) { - convert_to_string(&lfchars); + lfchars = Z_STRVAL(tmp_zv); + + tmp_zv_p = &tmp_zv; + } else { + lfchars = Z_STRVAL_PP(ppval); + } } - } else { - ZVAL_STRING(&lfchars, "\r\n", 1); } err = _php_iconv_mime_encode(&retval, field_name, field_name_len, - field_value, field_value_len, line_len, Z_STRVAL(lfchars), scheme_id, + field_value, field_value_len, line_len, lfchars, scheme_id, out_charset, in_charset); _php_iconv_show_error(err, out_charset, in_charset TSRMLS_CC); @@ -2008,7 +2009,9 @@ PHP_FUNCTION(iconv_mime_encode) RETVAL_FALSE; } - zval_dtor(&lfchars); + if (tmp_zv_p != NULL) { + zval_dtor(tmp_zv_p); + } } /* }}} */ diff --git a/ext/iconv/tests/iconv004.phpt b/ext/iconv/tests/iconv004.phpt new file mode 100644 index 0000000000..0e40ed4fcc --- /dev/null +++ b/ext/iconv/tests/iconv004.phpt @@ -0,0 +1,10 @@ +--TEST-- +iconv_mime_encode() sanity cheeck. +--FILE-- + 1))); +?> +--EXPECT-- +string(19) ": =?ISO-8859-1?B??=" +string(19) ": =?ISO-8859-1?B??=" -- 2.40.0