php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #44624 [PATCH] Encoding translation does't work when posted multipart/form-data
Submitted: 2008-04-03 05:38 UTC Modified: 2008-11-02 01:00 UTC
Votes:5
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: sh_tanaka at mail dot goo dot ne dot jp Assigned:
Status: No Feedback Package: mbstring related
PHP Version: 5.2.5 OS: Solaris 8
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2008-04-03 05:38 UTC] sh_tanaka at mail dot goo dot ne dot jp
Description:
------------
Encoding translation of incomming posted data does't work when enctype attribute in from element is set to multipart/form-data.

We are plannning to upgrade PHP4.3.11 to 5.2.5 and now we are testing
all applications.
Translation of PHP4.3.11 is OK, but NO translation occurrs on PHP5.2.5.

Online manual( http://www.php.net/manual/en/ref.mbstring.php ) says,

> Note: In PHP 4.3.2 or earlier versions, there was a limitation in
> this functionality that mbstring does not perform character
> encoding conversion in POST data if the enctype attribute in the
> form element is set to multipart/form-data.

If conversion in PHP 5.2.5 is as same as PHP4.3.2 or earlier versions, online manual should be corrected.



 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-04-08 15:03 UTC] script-kid at hotmail dot co dot jp
Hi. I have the same problem with PHP-5.2.5 on RedHasES4.

I guess that sapi_module.input_filter in main/rfc1867.c seem to be
return 0 when post multipart/form-data. I confirmed this by putting Debug code.

main/rfc1867.c:925
>       if (sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) {
>         if (php_rfc1867_callback != NULL) {
>           multipart_event_formdata event_formdata;
>           size_t newlength = 0;
>
>           event_formdata.post_bytes_processed = SG(read_post_bytes);
>           event_formdata.name = param;
>           event_formdata.value = &value;
>           event_formdata.length = new_val_len;
>           event_formdata.newlength = &newlength;
>           if (php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC) == FAILURE) {
>             efree(param);
>             efree(value);
>             continue;
>           }
>           new_val_len = newlength;
>         }

So, The follow process is not done. 

main/rfc1867.c:943
>#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
>         if (php_mb_encoding_translation(TSRMLS_C)) {
>           php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
>                         &num_vars, &num_vars_max TSRMLS_CC);
>         } else {
>           safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
>         }
>#else
>         safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
>#endif
>       } else if (php_rfc1867_callback != NULL) {



It seem to work properly when I tyr to change code like that.

$ diff -u main/rfc1867.c.org main/rfc1867.c
--- main/rfc1867.c.org  2007-07-18 08:46:40.000000000 +0900
+++ main/rfc1867.c  2008-04-08 21:55:05.000000000 +0900
@@ -937,33 +937,34 @@
               efree(value);
               continue;
             }
             new_val_len = newlength;
           }

-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
-          if (php_mb_encoding_translation(TSRMLS_C)) {
-            php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
-                          &num_vars, &num_vars_max TSRMLS_CC);
-          } else {
-            safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
-          }
-#else
-          safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
-#endif
         } else if (php_rfc1867_callback != NULL) {
           multipart_event_formdata event_formdata;

           event_formdata.post_bytes_processed = SG(read_post_bytes);
           event_formdata.name = param;
           event_formdata.value = &value;
           event_formdata.length = value_len;
           event_formdata.newlength = NULL;
           php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC);
         }

+#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
+          if (php_mb_encoding_translation(TSRMLS_C)) {
+            php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
+                          &num_vars, &num_vars_max TSRMLS_CC);
+          } else {
+            safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
+          }
+#else
+          safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
+#endif
+
         if (!strcasecmp(param, "MAX_FILE_SIZE")) {
           max_file_size = atol(value);
         }
 [2008-10-25 13:23 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2008-11-02 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2011-08-17 02:37 UTC] y-sugino at is-visionary dot com
I also have the same problem with the following environment.

  (1) PHP 5.2.9 on CentOS 5.3
  (2) PHP 5.3.6 on CentOS 5.6
  (3) PHP-5.3-dev on CentOS 5.6
      (php5.3-201108170030.tar.bz2)

In my environments, script-kid's patch resolved no encoding
conversion problem, but it caused another new problem.

When using a parameter name with [], the posted value was
duplicated in $_POST like below:

  <select name="VALUES[]">
    <option value="1">1</option> # selected
    <option value="2">2</option>
    <option value="3">3</option>
  </select>

  ["VALUES"] =>
  array(2) {
    [0] =>
    string(1) "1"
    [1] =>
    string(1) "1"
  }

According to GDB's trace, sapi_module.input_filter in main/rfc1867.c
had a reference of php_sapi_filter() in ext/filter/filter.c.
This is because filter extension is enabled in PHP 5.2/5.3 by default.

php_sapi_filter() invokes php_register_variable_ex() and then returns 0
if arg is not PARSE_STRING.

In script-kid's patched main/rfc1867.c, safe_php_register_variable()
will be invoked after invoking sapi_module.input_filter().
I think this is the reason why $_POST had duplicate values.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 16 07:01:29 2024 UTC