1. tar包内文件名称校验
1. 读取tar包内所有的文件名称
export class TarReader {
fileInfo: any[]
buffer: string | ArrayBuffer
constructor() {
this.fileInfo = []
}
readFile(file) {
return new Promise(resolve => {
const reader = new FileReader()
reader.onload = event => {
this.buffer = event.target.result
this.fileInfo = []
this.readFileInfo()
resolve(this.fileInfo)
}
reader.readAsArrayBuffer(file)
})
}
readFileInfo() {
this.fileInfo = []
let offset = 0
let fileSize = 0
let fileName = ''
while (offset < (this.buffer as ArrayBuffer).byteLength - 512) {
fileName = this.readFileName(offset) // file name
if (fileName.length === 0) {
break
}
fileSize = this.readFileSize(offset)
this.fileInfo.push({
name: fileName,
size: fileSize,
headerOffset: offset
})
offset += 512 + 512 * Math.trunc(fileSize / 512)
if (fileSize % 512) {
offset += 512
}
}
}
getFileInfo() {
return this.fileInfo
}
readString(strOffset, size) {
const strView = new Uint8Array(this.buffer as ArrayBuffer, strOffset, size)
const i = strView.indexOf(0)
const td = new TextDecoder()
return td.decode(strView.slice(0, i))
}
readFileName(headerOffset) {
const name = this.readString(headerOffset, 100)
return name
}
readFileSize(headerOffset) {
// offset: 124
const szView = new Uint8Array(
this.buffer as ArrayBuffer,
headerOffset + 124,
12
)
let szStr = ''
for (let i = 0; i < 11; i++) {
szStr += String.fromCharCode(szView[i])
}
return parseInt(szStr, 8)
}
}
2. 校验tar包内文件名称
// 名称校验规则
const nameRule = str => {
return !/^[a-z|A-Z|0-9|\/\.\#\-|_|]{1,250}$/g.test(str)
}
// 根据名称规则校验tar包内文件名称
const validateTarFileNames = async file => {
try {
const instance = new TarReader()
const list = (await instance.readFile(file)) as any[]
if (Array.isArray(list)) {
for (const item of list) {
const fileName = item.name
if (nameRule(fileName)) {
return true
}
}
}
} catch {
return false
}
}
2. zip包内文件名称校验
使用jszip插件
const validateZipFileNames = async file => {
try {
const zip = new JSZip()
const data = await file
await zip.loadAsync(data)
// 获取所有文件列表
const files = Object.keys(zip.files)
// 遍历每个文件并判断文件名是否符合条件
for (const fileName of files) {
if (nameRule(fileName)) {
return true
}
}
} catch (error) {
return false
}
}
3. 使用
// 如果是tar压缩包
const tarRes: any = await validateTarFileNames(file)
if (tarRes) {
console.log('压缩包内有名称不符合校验规则');
}
// 如果是zip压缩包
const zipRes = await validateZipFileNames(file)
if (zipRes) {
console.log('压缩包内有名称不符合校验规则');
}