Skip to content

Commit

Permalink
fix: make extension patterns match the end of the file name (#5652)
Browse files Browse the repository at this point in the history
* fix: make extension patterns match the end of the file name

* fix: make the regex safari-compatible

* refactor: remove extra lines

* refactor: update naming for clarification

* refactor: rename file name and extension in test

* Update packages/upload/test/adding-files.test.js

Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>

* test: add a test for rejecting files that have partial extension match

* refactor: extract regex logic in a loop and make it a function

* Update packages/upload/src/vaadin-upload.js

Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>

* refactor: change the call in order to align with the naming change

* fix: return null instead of undefined

---------

Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>
  • Loading branch information
2 people authored and vaadin-bot committed Mar 13, 2023
1 parent 97f47a8 commit b9bb6ed
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
28 changes: 22 additions & 6 deletions packages/upload/src/vaadin-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,26 @@ class Upload extends ElementMixin(ThemableMixin(ControllerMixin(PolymerElement))
];
}

/** @private */
get __acceptRegexp() {
if (!this.accept) {
return null;
}
const processedTokens = this.accept.split(',').map((token) => {
let processedToken = token.trim();
// Escape regex operators common to mime types
processedToken = processedToken.replace(/[+.]/gu, '\\$&');
// Make extension patterns match the end of the file name
if (processedToken.startsWith('\\.')) {
processedToken = `.*${processedToken}$`;
}
// Handle star (*) wildcards
return processedToken.replace(/\/\*/gu, '/.*');
});
// Create accept regex
return new RegExp(`^(${processedTokens.join('|')})$`, 'iu');
}

/** @protected */
ready() {
super.ready();
Expand Down Expand Up @@ -879,12 +899,8 @@ class Upload extends ElementMixin(ThemableMixin(ControllerMixin(PolymerElement))
);
return;
}
const fileExt = file.name.match(/\.[^.]*$|$/u)[0];
// Escape regex operators common to mime types
const escapedAccept = this.accept.replace(/[+.]/gu, '\\$&');
// Create accept regex that can match comma separated patterns, star (*) wildcards
const re = new RegExp(`^(${escapedAccept.replace(/[, ]+/gu, '|').replace(/\/\*/gu, '/.*')})$`, 'iu');
if (this.accept && !(re.test(file.type) || re.test(fileExt))) {
const re = this.__acceptRegexp;
if (re && !(re.test(file.type) || re.test(file.name))) {
this.dispatchEvent(
new CustomEvent('file-reject', {
detail: { file, error: this.i18n.error.incorrectFileType },
Expand Down
14 changes: 14 additions & 0 deletions packages/upload/test/adding-files.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ describe('adding files', () => {
expect(upload.files.length).to.equal(1);
});

it('should allow files with extensions containing multiple dots', () => {
upload.accept = 'image/*,.bar.baz,video/*';
file.name = 'foo.bar.baz';
upload._addFiles([file]);
expect(upload.files).to.have.lengthOf(1);
});

it('should reject files that have partial extension match', () => {
upload.accept = 'image/*,.bar.baz,video/*';
file.name = 'foo.baz';
upload._addFiles([file]);
expect(upload.files).to.have.lengthOf(0);
});

it('should allow files with correct mime type', () => {
upload.accept = 'application/x-octet-stream';
upload._addFiles([file]);
Expand Down

0 comments on commit b9bb6ed

Please sign in to comment.