]> granicus.if.org Git - php/commitdiff
- MFH: Add sanity check in iconv_mime_encode(). Leaving the third parameter
authorMoriyoshi Koizumi <moriyoshi@php.net>
Wed, 23 Mar 2005 23:08:25 +0000 (23:08 +0000)
committerMoriyoshi Koizumi <moriyoshi@php.net>
Wed, 23 Mar 2005 23:08:25 +0000 (23:08 +0000)
  unspecified would yield bus error.
- MFH: Add testcase for the bug.

ext/iconv/iconv.c
ext/iconv/tests/iconv004.phpt [new file with mode: 0644]

index ae03c705bf7121711f05e439894bd81338a4546f..b8c76c5bedd10656bcd4ce8c140fde57826264d1 100644 (file)
@@ -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 (file)
index 0000000..0e40ed4
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+iconv_mime_encode() sanity cheeck.
+--FILE--
+<?php
+var_dump(iconv_mime_encode('', ''));
+var_dump(iconv_mime_encode('', '', array('line-break-chars' => 1)));
+?>
+--EXPECT--
+string(19) ": =?ISO-8859-1?B??="
+string(19) ": =?ISO-8859-1?B??="