Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

the same field's value have different type 'enctype="multipart/form-data" ' #138

Open
blue5tar opened this Issue Feb 25, 2012 · 4 comments

Comments

Projects
None yet
3 participants

sorry, my English is poor!!

<form method="post">
    <input type="checkbox" name="username" value="" />
    <input type="checkbox" name="username" value="" />
</form>

form.on('field', function(field, value) {
    if  (the form have  'enctype="multipart/form-data" ') {
        username is not a array 
    }
    if (the form have no 'enctype="multipart/form-data" ') {
        username is a array
    }
}
Collaborator

svnlto commented Dec 7, 2012

would you mind creating a test case for this?

rcprior commented Nov 4, 2013

Using the following script

var formidable = require('formidable'),
    http = require('http'),
    util = require('util');

http.createServer(function(req, res) {
  if (req.method.toLowerCase() == 'post') {
    // Parse an upload
    var form = new formidable.IncomingForm();

    form.parse(req, function(err, fields, files) {
      res.writeHead(200, {'content-type': 'text/plain'});
      res.end(util.inspect(fields));
    });

    return;

  } else if (req.method.toLowerCase() == 'get') {
    // Stream the form.html file
    res.writeHead(200, {'content-type': 'text/html'});
    res.write('<!DOCTYPE html>\n');
    res.end('<html><head><title>Bug</title></head><body><form method="post">' +
       '<input type="text" name="test" value="val1" />' +
       '<input type="text" name="test" value="val2" />' +
       '<input type="submit" value="Normal" />' +
       '<input type="submit" value="Multipart" formenctype="multipart/form-data" />' +
       '</form></body></html>');
  } else {
    res.writeHead(405, {'content-type': 'text/plain'});
    res.end('Method ' + req.method + ' not supported');
  }

}).listen(9000);

and point your browser at port 9000 of your server.
If you submit using the "Normal" button, no enctype is specified, and the form is submitted with enctype="application/x-www-form-urlencoded". Server will output

{ test: [ 'val1', 'val2' ] }

However, if you hit the "Multipart" button, the form is submitted with enctype="multipart/form-data", and the output will be

{ test: 'val2' }

I.e., if you have a field with multiple values (e.g., a select multiple), only the last selected value will be available.

rcprior commented Nov 4, 2013

To fix this issue, please apply the following patch:

--- incoming_form.js       2013-11-04 17:47:08.407799172 +0000
+++ incoming_form.js    2013-11-04 17:54:00.845847743 +0000
@@ -80,7 +80,14 @@
     var fields = {}, files = {};
     this
       .on('field', function(name, value) {
-        fields[name] = value;
+        if (fields.hasOwnProperty(name)) {
+          if (!(fields[name] instanceof Array)) {
+            fields[name] = [ fields[name] ];
+          }
+          fields[name].push(value);
+        } else {
+          fields[name] = value;
+        }
       })
       .on('file', function(name, file) {
         files[name] = file;

rcprior commented Nov 5, 2013

By the way, a similar problem to multi-valued fields occurs with the submission of a form with multiple file fields having the same name. In this case, several temporary files will be created, but the main script will only see the last one. The temporary files that were not seen by the main script can accumulate until they take up all disk space, thus opening a vector for a denial of service attack.
The solution is applying the same principle of normal fields to file fields (i.e., passing a vector when multiple file fields with the same name are submitted).

zhangleipro added a commit to zhangleipro/node-formidable that referenced this issue Jan 27, 2016

This was referenced Jan 27, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment