ColdFusion 10 Beta: Multiple HTML5 multiple uploads bug

No, I didn’t type multiple twice by mistake. This post is about Adobe ColdFusion 10 Beta release and its support of HTML5’s <input type="file" name="bob" multiple="multiple" />. But not just one of them, imagine a form with 2 or more “multiple” uploads. Well currently that’s about all you should be doing, imagining, since it’s not properly supported in the current Beta.

The code

&lt;cfscript&gt;
  if (cgi.request_method == &apos;POST&apos;) {
    WriteDump(var = form, label = &quot;Form Scope&quot;);
    for (field in form) {
      form[field] = ListToArray(form[field]);
    }
    WriteDump(var = form, label = &quot;Form Scope - Parsed&quot;);
    // Dump the temporary files created by the uploads
    WriteDump(var = form.gettempfiles(), label = &quot;Form.getTempFiles()&quot;);
    // Dump the &quot;parts&quot; of the upload request CF found.
    WriteDump(var = form.getPartsArray(), label = &quot;Form.getPartsArray()&quot;);

    // Parse form.getPartsArray() to show what uploads were processed.
    uploads = {};
    ArrayEach(form.getPartsArray(), function(el) {
      fieldName = el.getName();
      if (Not StructKeyExists(uploads, fieldName)) {
        uploads[fieldName] = el.getFileName();
      } else if (Not IsArray(uploads[fieldName])) {
        uploads[fieldName] = [uploads[fieldName], el.getFileName()];
      } else {
        ArrayAppend(uploads[fieldName], el.getFileName());
      }
    });
    WriteDump(uploads);
  }
&lt;/cfscript&gt;
&lt;cfif cgi.request_method eq &apos;POST&apos;&gt;
  &lt;cffile action=&quot;uploadAll&quot; destination=&quot;#ExpandPath(&apos;./uploads/&apos;)#&quot; /&gt;
&lt;/cfif&gt;

&lt;form method=&quot;post&quot; enctype=&quot;multipart/form-data&quot; action=&quot;uploads.cfm&quot;&gt;
  &lt;label&gt;First:
    &lt;input type=&quot;file&quot; name=&quot;first&quot; multiple=&quot;multiple&quot; /&gt;
  &lt;/label&gt;&lt;br /&gt;
  &lt;label&gt;Second:
    &lt;input type=&quot;file&quot; name=&quot;second&quot; multiple=&quot;multiple&quot; /&gt;
  &lt;/label&gt;&lt;br /&gt;
  &lt;label&gt;Third:
    &lt;input type=&quot;file&quot; name=&quot;third&quot; multiple=&quot;multiple&quot; /&gt;
  &lt;/label&gt;&lt;br /&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Upload&quot; /&gt;
&lt;/form&gt;

Steps to recreate:

  1. Have a few files handy to test the uploading. I used 7 uniquely named files, all of them images too (not important but handy later).
  2. Open the page in a browser (with the right HTML5 support).
  3. Provide each upload field with something to upload. I supplied the following:

    • “first” was given 1 file.
    • “second” was given 2 files.
    • “third” was give 4 files.
  4. Submit the form.

What just happened?

Well it’s always a good idea to start at the very beginning of a story…

Once upon a time:

  • ColdFusion received your file uploads.
  • It then looped over those files, throwing the data into temporary files (usually getTempDirectory()) and storing their original file names somewhere safe.
  • Then it finally got around to executing that .cfm file of yours.

So far so good… except, as you’ve probably guessed from reading this so far, it’s not good.

What went wrong?

ColdFusion 10 Beta appears to try and copy with multiple upload fields, but doesn’t cope with a multiple of those fields. First, let’s look inside the form scope.

Form.fieldnames looks about right, you can see each fieldname multiple times and that matches up with the number of uploads each field received. form.first and form.second seem fine as well, showing the temporary directory path where their uploads are stored. But what’s up with form.third? It appears to contain 5 entries instead of 4, 2 of which are identical paths to the files from form.second!? Let’s dig a little deeper shall we? Hidden in the form scope is form.getTempFiles(), one of those undocumented little gems that can give a little insider information on what’s happening.

Now it’s starting to become obvious that there’s a problem. “first” looks dandy, one java.io.File pointing at the upload being held in the temporary directory. But I’m pretty sure “second” and “third” didn’t have 5 uploads each. How about another undocumented goodie? form.getPartsArray() seems to contain information about the uploads and their form fields.

Nice, tells us exactly what was uploaded when we dig into what was returned via .getName() for the form field and .getFileName() for the original upload filename, not that nasty temporary one it has now.

So what happened?

Here begins a bit of guesswork. It appears that ColdFusion is looping though the uploads correctly, as seen in form.getPartsArray(). The problem comes somewhere internally where it’s storing those files and their temporary paths, somewhere it breaks. What we end up with is missing data, I only got 6 files in my upload folder and then it threw an error. Plus data corruption, as 3 files (memory-3week.png, requests-3week.png and threads-3week.png) all had content from other files (in that form submission).

My guess for the error, seems like ColdFusion is looping over the form scope and matching that information against that stored in form.getPartsArray(). That’s fine for “first” and “second”, but “third” has 5 entries but in getPartsArray it only had 4. Error thrown. Wild guess for the data corruption, judging from form.getTempFiles(). Where ever it’s storing the upload information, it’s using a variable that either isn’t being reset properly for each field (so a pointers survive to the next form field) or it wasn’t properly scoped somehow. Only those Adobe engineers know for sure.

Vote

If you’re planning on using HTML5 uploads in the future, there’s always the chance you might use multiple fields for some reason and then hit this bug. So hit back and vote for it to be fixed ;)

https://bugbase.adobe.com/index.cfm?event=bug&id=3132537

*Update*

The bug record with Adobe has now been updated with a status of “ToFix” and they’ve set it as verified :)


Comments


David Boyer
David Boyer

Full-stack web developer from Cardiff, Wales. With a love for JavaScript, especially from within Node.js.

More...