formidable icon indicating copy to clipboard operation
formidable copied to clipboard

Specific file names cause the extension to not be set correctly with options.keepExtensions "test(.123).pdf"

Open spudcud opened this issue 1 year ago • 2 comments

Support plan

  • Which support plan is this issue covered by? (Community, Sponsor, Enterprise): community
  • Currently blocking your project/work? (yes/no):
  • Affecting a production system? (yes/no): yes

Context

  • Node.js version: 18.18.0
  • Release Line of Formidable (Legacy, Current, Next): Current
  • Formidable exact version: 3.5.1
  • Environment (node, browser, native, OS): node
  • Used with (popular names of modules):

What are you trying to achieve or the steps to reproduce?

I am setting the option keepExtensions: true but when the file contains a period in the name with other characters it screws up the filePath created. It takes the first instance of the period and uses it instead of the final period. What is odd is I looked at using options.filename to get this corrected (which works) but the ext passed into the function is correctly '.pdf'.

import formidable from 'formidable';

const getFile = (req) => {
  return new Promise((resolve, reject) => {
    const form = formidable({
      keepExtensions: true,
    });

    form.parse(req, (err, fields, files) => {
      if (err) {
        return reject(err);
      }

      const { file: fileArr } = files;
      const file = fileArr[0];

      return resolve({
        path: file.filepath,
        fileName: file.originalFilename,
        uploadType: fields?.uploadType?.[0],
        docType: fields?.docType?.[0],
      });
    });
  });
};

export default getFile;

What was the result you got?

These are files we received from clients that caused issues processing: 'test(.123).pdf' - became '8316b5c96ab192694f1fd3a00.123' 'EERS 1.1-CUR.pdf' - became '8316b5c96ab192694f1fd3a01.1'

image

What result did you expect?

The filepath was expected to have the correct extension .pdf

spudcud avatar Oct 03 '24 17:10 spudcud

If the filename option is not provided the extension that is used will start at the first dot. This allows extensions such as x.test.js to be preserved. The characters allowed here are only numbers and ascii letters. That is why it cuts off at the first parentheses

When the filename option is provided then the filename function will be called with name, ext, part arguments and in this case the ext, name come from nodejs path.parse function. In that case both are not checked for invalid file characters. And the ext will be starting from the last dot and the name will be everything before.

Do you think the formidable library should change ?

In your case, you could overwrite _getExtension private to get a desired result.

GrosSacASac avatar Oct 21 '24 13:10 GrosSacASac

In this specific case I would expect formidable to retain the extension. I have worked around this by setting the file manually but it took encountering these failures in production in order to see what the root cause was.

spudcud avatar Oct 25 '24 12:10 spudcud