2

I am trying to use this open source image uploader: https://github.com/blueimp

The documentation says that the function to match on File Type can be used to match on file name also.

https://github.com/blueimp/jQuery-File-Upload/blob/7d46990486ff08acfc001b6368b09bce6712c2c2/js/jquery.fileupload-validate.js

Can anyone see a way to use this to match on and restrict special characters in the file names?

Here is the RegEx that will match the characters that I specifically want to exclude. I am trying to prevent end users from using special characters in file names, instead of just depending on training them. English is the only concern in this case.

[&~@#$^*()_+=/:?;\\|<>"',!%]

Here is the snipit from the source code (open source) that would evaluate it. Full code available at the link above.

 // The File Upload Validation plugin extends the fileupload widget
// with file validation functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {

    options: {
        /*
        // The regular expression for allowed file types, matches
        // against either file type or file name:
        acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
        // The maximum allowed file size in bytes:
        maxFileSize: 10000000, // 10 MB
        // The minimum allowed file size in bytes:
        minFileSize: undefined, // No minimal file size
        // The limit of files to be uploaded:
        maxNumberOfFiles: 10,
        */

        // Function returning the current number of files,
        // has to be overriden for maxNumberOfFiles validation:
        getNumberOfFiles: $.noop,

        // Error and info messages:
        messages: {
            maxNumberOfFiles: 'Maximum number of files exceeded',
            acceptFileTypes: 'File type not allowed',
            maxFileSize: 'File is too large',
            minFileSize: 'File is too small'
        }
    },

    processActions: {

        validate: function (data, options) {
            if (options.disabled) {
                return data;
            }
            var dfd = $.Deferred(),
                settings = this.options,
                file = data.files[data.index],
                fileSize;
            if (options.minFileSize || options.maxFileSize) {
                fileSize = file.size;
            }
            if ($.type(options.maxNumberOfFiles) === 'number' &&
                    (settings.getNumberOfFiles() || 0) + data.files.length >
                        options.maxNumberOfFiles) {
                file.error = settings.i18n('maxNumberOfFiles');
            } else if (options.acceptFileTypes &&
                    !(options.acceptFileTypes.test(file.type) ||
                    options.acceptFileTypes.test(file.name))) {
                file.error = settings.i18n('acceptFileTypes');
            } else if (fileSize > options.maxFileSize) {
                file.error = settings.i18n('maxFileSize');
            } else if ($.type(fileSize) === 'number' &&
                    fileSize < options.minFileSize) {
                file.error = settings.i18n('minFileSize');
            } else {
                delete file.error;
            }
            if (file.error || data.files.error) {
                data.files.error = true;
                dfd.rejectWith(this, [data]);
            } else {
                dfd.resolveWith(this, [data]);
            }
            return dfd.promise();
        }

    }

});

Edit: Some things I have tried:

Thanks for the quick responses. Some things I have tried here: Many of these return the the match even it it the name is preceeded by an invalid character. See http://regexr.com/3be9o I don't want asdf&ghjik.jpg to match as valid.

I guess I really want a-z A-Z 0-9 - _

[^&~@#$^*()_+=/:?;\\|<>"',!%]([\w]+\-*[\w]+)+(\.|\/)(gif|jpe?g|png)

([^&~@#$^*()_+=/:?;\\|<>"',!%])?([\w]+\-*[\w]+)+(\.|\/)(gif|jpe?g|png)

([\w]+\-+[\w]+)+(\.|\/)(gif|jpe?g|png)

[^&~@#$^*()_+=/:?;\\|<>"',!%]*(\.jpg)|[^&~@#$^*()_+=/:?;\\|<>"',!%]*(\.png)|

[^&~@#$^*()_+=/:?;\\|<>"',!%]*(\.gif)|[^&~@#$^*()_+=/:?;\\|<>"',!%]*(\.jpeg)
rustyspark
  • 195
  • 1
  • 9
  • 2
    Instead of disallowing specific things, specify what's allowed. – Etheryte Jul 21 '15 at 20:17
  • If it's just regex, `[A-Z,a-z,0-9]` only allowed for filenames; otherwise, output error. If you want to include certain characters as well, like period, hyphen, underscore, just prepend an escape character `\.,\_,\-`. I'm not sure about the best way in javascript. Why don't you include what you've tried? – ILMostro_7 Jul 21 '15 at 20:22
  • 1
    @ILMostro_7 that character group will also include the comma `,` as that is not a delimiter inside of character groups. Those have no delimiter, it's just a bunch of chars. Also, there is no need to escape an underscore `_` and you do not need to escape a dash `-` if it's the last thing in the character group. That gives `[a-zA-Z0-9\._-]`. – simbabque Jul 21 '15 at 20:36
  • Edited original with some clarifications based on feedback. Thanks for quick reply! – rustyspark Jul 21 '15 at 21:10

1 Answers1

1

As @Nit pointed out in a comment, white-listing rules is always better than black-listing. This means always try to specify what's allowed rather than what's forbidden as it is very easy to miss something (Did you think of pound sign? Non-English alphabets? UTF characters in general?)

As a start you can use the very simple [\w\.\- ]

The \w metacharacter is used to find a word character.

A word character is a character from a-z, A-Z, 0-9, including the _ (underscore) character.

For a good explanation on what are good/bad file names in Windows take a look at this thread.

Community
  • 1
  • 1
SDekov
  • 9,276
  • 1
  • 20
  • 50
  • Thanks @Stoyan When I try that it selects partial matches that are invalid. How do I prevent that? See http://regexr.com/3bed7 – rustyspark Jul 21 '15 at 21:30
  • 1
    You would want to use `^` and `$` around your regex. This means it should start and end with (i.e matches the whole string) [demo](http://regexr.com/3begv) – SDekov Jul 22 '15 at 08:49
  • I think that was almost what I needed, but then I also needed to enable the multiline flag (in my regex demo) so that it would only pay attention to a match on a single line. This appears to be the final version that works. `/^([\w\.\- ]+(\.|\/)(gif|jpe?g|png))$/gm` http://regexr.com/3bed7 – rustyspark Jul 22 '15 at 12:55