mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Update:Max filename to 255 bytes in utf-16 #1261
This commit is contained in:
parent
2af7b6b6f1
commit
4d8e2a1279
@ -30,23 +30,26 @@ Vue.prototype.$addDaysToDate = (jsdate, daysToAdd) => {
|
|||||||
return date
|
return date
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.prototype.$sanitizeFilename = (input, colonReplacement = ' - ') => {
|
Vue.prototype.$sanitizeFilename = (filename, colonReplacement = ' - ') => {
|
||||||
if (typeof input !== 'string') {
|
if (typeof filename !== 'string') {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Max is actually 255-260 for windows but this leaves padding incase ext wasnt put on yet
|
// Most file systems use number of bytes for max filename
|
||||||
const MAX_FILENAME_LEN = 240
|
// to support most filesystems we will use max of 255 bytes in utf-16
|
||||||
|
// Ref: https://doc.owncloud.com/server/next/admin_manual/troubleshooting/path_filename_length.html
|
||||||
|
// Issue: https://github.com/advplyr/audiobookshelf/issues/1261
|
||||||
|
const MAX_FILENAME_BYTES = 255
|
||||||
|
|
||||||
var replacement = ''
|
const replacement = ''
|
||||||
var illegalRe = /[\/\?<>\\:\*\|"]/g
|
const illegalRe = /[\/\?<>\\:\*\|"]/g
|
||||||
var controlRe = /[\x00-\x1f\x80-\x9f]/g
|
const controlRe = /[\x00-\x1f\x80-\x9f]/g
|
||||||
var reservedRe = /^\.+$/
|
const reservedRe = /^\.+$/
|
||||||
var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i
|
const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i
|
||||||
var windowsTrailingRe = /[\. ]+$/
|
const windowsTrailingRe = /[\. ]+$/
|
||||||
var lineBreaks = /[\n\r]/g
|
const lineBreaks = /[\n\r]/g
|
||||||
|
|
||||||
var sanitized = input
|
sanitized = filename
|
||||||
.replace(':', colonReplacement) // Replace first occurrence of a colon
|
.replace(':', colonReplacement) // Replace first occurrence of a colon
|
||||||
.replace(illegalRe, replacement)
|
.replace(illegalRe, replacement)
|
||||||
.replace(controlRe, replacement)
|
.replace(controlRe, replacement)
|
||||||
@ -55,13 +58,25 @@ Vue.prototype.$sanitizeFilename = (input, colonReplacement = ' - ') => {
|
|||||||
.replace(windowsReservedRe, replacement)
|
.replace(windowsReservedRe, replacement)
|
||||||
.replace(windowsTrailingRe, replacement)
|
.replace(windowsTrailingRe, replacement)
|
||||||
|
|
||||||
|
// Check if basename is too many bytes
|
||||||
|
const ext = Path.extname(sanitized) // separate out file extension
|
||||||
|
const basename = Path.basename(sanitized, ext)
|
||||||
|
const extByteLength = Buffer.byteLength(ext, 'utf16le')
|
||||||
|
const basenameByteLength = Buffer.byteLength(basename, 'utf16le')
|
||||||
|
if (basenameByteLength + extByteLength > MAX_FILENAME_BYTES) {
|
||||||
|
const MaxBytesForBasename = MAX_FILENAME_BYTES - extByteLength
|
||||||
|
let totalBytes = 0
|
||||||
|
let trimmedBasename = ''
|
||||||
|
|
||||||
if (sanitized.length > MAX_FILENAME_LEN) {
|
// Add chars until max bytes is reached
|
||||||
var lenToRemove = sanitized.length - MAX_FILENAME_LEN
|
for (const char of basename) {
|
||||||
var ext = Path.extname(sanitized)
|
totalBytes += Buffer.byteLength(char, 'utf16le')
|
||||||
var basename = Path.basename(sanitized, ext)
|
if (totalBytes > MaxBytesForBasename) break
|
||||||
basename = basename.slice(0, basename.length - lenToRemove)
|
else trimmedBasename += char
|
||||||
sanitized = basename + ext
|
}
|
||||||
|
|
||||||
|
trimmedBasename = trimmedBasename.trim()
|
||||||
|
sanitized = trimmedBasename + ext
|
||||||
}
|
}
|
||||||
|
|
||||||
return sanitized
|
return sanitized
|
||||||
|
@ -183,16 +183,19 @@ module.exports.sanitizeFilename = (filename, colonReplacement = ' - ') => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Max is actually 255-260 for windows but this leaves padding incase ext wasnt put on yet
|
// Most file systems use number of bytes for max filename
|
||||||
const MAX_FILENAME_LEN = 240
|
// to support most filesystems we will use max of 255 bytes in utf-16
|
||||||
|
// Ref: https://doc.owncloud.com/server/next/admin_manual/troubleshooting/path_filename_length.html
|
||||||
|
// Issue: https://github.com/advplyr/audiobookshelf/issues/1261
|
||||||
|
const MAX_FILENAME_BYTES = 255
|
||||||
|
|
||||||
var replacement = ''
|
const replacement = ''
|
||||||
var illegalRe = /[\/\?<>\\:\*\|"]/g
|
const illegalRe = /[\/\?<>\\:\*\|"]/g
|
||||||
var controlRe = /[\x00-\x1f\x80-\x9f]/g
|
const controlRe = /[\x00-\x1f\x80-\x9f]/g
|
||||||
var reservedRe = /^\.+$/
|
const reservedRe = /^\.+$/
|
||||||
var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i
|
const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i
|
||||||
var windowsTrailingRe = /[\. ]+$/
|
const windowsTrailingRe = /[\. ]+$/
|
||||||
var lineBreaks = /[\n\r]/g
|
const lineBreaks = /[\n\r]/g
|
||||||
|
|
||||||
sanitized = filename
|
sanitized = filename
|
||||||
.replace(':', colonReplacement) // Replace first occurrence of a colon
|
.replace(':', colonReplacement) // Replace first occurrence of a colon
|
||||||
@ -203,12 +206,25 @@ module.exports.sanitizeFilename = (filename, colonReplacement = ' - ') => {
|
|||||||
.replace(windowsReservedRe, replacement)
|
.replace(windowsReservedRe, replacement)
|
||||||
.replace(windowsTrailingRe, replacement)
|
.replace(windowsTrailingRe, replacement)
|
||||||
|
|
||||||
if (sanitized.length > MAX_FILENAME_LEN) {
|
// Check if basename is too many bytes
|
||||||
var lenToRemove = sanitized.length - MAX_FILENAME_LEN
|
const ext = Path.extname(sanitized) // separate out file extension
|
||||||
var ext = Path.extname(sanitized)
|
const basename = Path.basename(sanitized, ext)
|
||||||
var basename = Path.basename(sanitized, ext)
|
const extByteLength = Buffer.byteLength(ext, 'utf16le')
|
||||||
basename = basename.slice(0, basename.length - lenToRemove)
|
const basenameByteLength = Buffer.byteLength(basename, 'utf16le')
|
||||||
sanitized = basename + ext
|
if (basenameByteLength + extByteLength > MAX_FILENAME_BYTES) {
|
||||||
|
const MaxBytesForBasename = MAX_FILENAME_BYTES - extByteLength
|
||||||
|
let totalBytes = 0
|
||||||
|
let trimmedBasename = ''
|
||||||
|
|
||||||
|
// Add chars until max bytes is reached
|
||||||
|
for (const char of basename) {
|
||||||
|
totalBytes += Buffer.byteLength(char, 'utf16le')
|
||||||
|
if (totalBytes > MaxBytesForBasename) break
|
||||||
|
else trimmedBasename += char
|
||||||
|
}
|
||||||
|
|
||||||
|
trimmedBasename = trimmedBasename.trim()
|
||||||
|
sanitized = trimmedBasename + ext
|
||||||
}
|
}
|
||||||
|
|
||||||
return sanitized
|
return sanitized
|
||||||
|
Loading…
Reference in New Issue
Block a user