tdesign-vue
tdesign-vue copied to clipboard
[upload] 文件上传的 accept 设置为特殊类型时,不会正常接受对应类型的文件
tdesign-vue 版本
tdesign-vue 1.8.3
重现链接
https://codesandbox.io/p/sandbox/tdesign-vue-demo-forked-w74mxt?file=%2Fsrc%2Fdemo.vue%3A16%2C17
重现步骤
在页面上放置 TUpload 组件,设置允许拖拽。
设置 accept 属性,预期只接受指定类型的文件。示例代码中 accept=".p12" ,预期只接收扩展名为 p12 的文件。
从资源管理器拖动 p12 类型的文件到上传组件内。
期望结果
拖动文件的类型与预设 accept 类型一致,应当被接受。
实际结果
拖动文件没有被接受,文件列表中不会出现刚拖动过来的项目。
框架版本
Vue(2.6.14)
浏览器版本
Chrome(112.0.5615.138)
系统版本
Windows 10
Node版本
16.16.0
补充说明
检查源代码后发现,问题出在公用库 tdesign-common 的 代码 /js/upload/utils.ts 中。以下是有问题的代码:
export function validateFileType(accept: string, fileType: string, fileName?: string) {
const tmpFileType = fileType || fileName;
if (!accept) return true;
if (!tmpFileType) return false;
const acceptList = accept.split(',').map((v) => v.trim());
for (let i = 0, len = acceptList.length; i < len; i++) {
const oneRule = acceptList[i];
if (INPUT_FILE_MAP[oneRule] && INPUT_FILE_MAP[oneRule].test(tmpFileType)) {
return true;
}
const regExp = new RegExp(oneRule, 'i');
if (regExp.test(tmpFileType)) {
return true;
}
}
return false;
}
此代码存在两个严重问题:
-
在循环之前,先用
fileType与fileName两个参数做了一个或运算,得到结果tmpFileType在循环内使用。循环中如果 mime 类型匹配不成功,就会用accrept拆分出来的字符串创建一个正则表达式对象,然后对tmpFileType变量进行检测。 问题是,示例代码运行到此处时,创建的正则表达式是基于".p12"的,而tmpFileType实际上取的是文件 mime 类型(application/x-pkcs12),而不是文件名。因此这里的正则表达式会检测失败。 正确的做法应该是在循环内分别检测文件类型和文件名(regExp.test(fileType ) || regExp.test(fileName)),而不是在循环之前先做或运算,导致文件名在判断过程中被忽略。 -
new RegExp()调用时,没有对oneRule进行安全转换。如果oneRule中包含特殊字符,例如*,就会导致程序报错。
👋 @sagittarius-rev,感谢给 TDesign 提出了 issue。 请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。
♥️ 有劳 @chaishi @ctudoudou @uyarn @brianzhang @byq1213 @chaishi 尽快确认问题。 确认有效后将下一步计划和可能需要的时间回复给 @sagittarius-rev 。