mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-24 17:26:10 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
0e3a56826d
1 changed files with 92 additions and 13 deletions
|
|
@ -17,7 +17,6 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/fs"
|
||||
"mime"
|
||||
|
|
@ -247,23 +246,103 @@ func FilterUploadFileName(name string) string {
|
|||
}
|
||||
|
||||
func TruncateLenFileName(name string) (ret string) {
|
||||
// 插入资源文件时文件名长度最大限制 189 字节 https://github.com/siyuan-note/siyuan/issues/7099
|
||||
// 插入资源文件时文件名长度最大限制 189 字节
|
||||
const maxTotal = 189
|
||||
|
||||
ext := filepath.Ext(name)
|
||||
var byteCount int
|
||||
truncated := false
|
||||
buf := bytes.Buffer{}
|
||||
for _, r := range name {
|
||||
byteCount += utf8.RuneLen(r)
|
||||
if 189-len(ext) < byteCount {
|
||||
truncated = true
|
||||
base := name[:len(name)-len(ext)]
|
||||
|
||||
id := ast.NewNodeID()
|
||||
// 预留 "-" + id + "-" 的字节数
|
||||
reservedForID := len(id) + 2
|
||||
|
||||
available := maxTotal - len(ext) - reservedForID
|
||||
if available <= 0 {
|
||||
// 空间不足以保留 base,退回到 "-id-" + ext(若仍超限则只返回扩展名)
|
||||
candidate := "-" + id + "-" + ext
|
||||
if len(candidate) <= maxTotal {
|
||||
return candidate
|
||||
}
|
||||
if len(ext) <= maxTotal {
|
||||
return ext
|
||||
}
|
||||
return ext
|
||||
}
|
||||
|
||||
// 若 base 整体在可用字节内,直接返回原名
|
||||
if len(base) <= available {
|
||||
return name
|
||||
}
|
||||
|
||||
runes := []rune(base)
|
||||
n := len(runes)
|
||||
if n == 0 {
|
||||
candidate := "-" + id + "-" + ext
|
||||
if len(candidate) <= maxTotal {
|
||||
return candidate
|
||||
}
|
||||
if len(ext) <= maxTotal {
|
||||
return ext
|
||||
}
|
||||
return ext
|
||||
}
|
||||
|
||||
// 计算每个 rune 的字节长度
|
||||
runeBytes := make([]int, n)
|
||||
for i, r := range runes {
|
||||
runeBytes[i] = utf8.RuneLen(r)
|
||||
}
|
||||
|
||||
// 从后往前尝试最多保留 3 个 rune,找到最大的 tailSize 使得 tailBytes <= available
|
||||
tailSize := 0
|
||||
tailBytes := 0
|
||||
for t := 1; t <= 3 && t <= n; t++ {
|
||||
b := 0
|
||||
for i := n - t; i < n; i++ {
|
||||
b += runeBytes[i]
|
||||
}
|
||||
if b <= available {
|
||||
tailSize = t
|
||||
tailBytes = b
|
||||
} else {
|
||||
break
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
}
|
||||
if truncated {
|
||||
buf.WriteString(ext)
|
||||
|
||||
if tailSize == 0 {
|
||||
// 连一个尾部 rune 都放不下,回退到 "-id-" 或扩展名
|
||||
candidate := "-" + id + "-" + ext
|
||||
if len(candidate) <= maxTotal {
|
||||
return candidate
|
||||
}
|
||||
if len(ext) <= maxTotal {
|
||||
return ext
|
||||
}
|
||||
return ext
|
||||
}
|
||||
ret = buf.String()
|
||||
|
||||
// 可用于前缀的字节
|
||||
availFront := available - tailBytes
|
||||
// 前缀最多不能覆盖到尾部
|
||||
maxFrontCount := n - tailSize
|
||||
|
||||
var frontRunes []rune
|
||||
frontBytes := 0
|
||||
for i := 0; i < maxFrontCount; i++ {
|
||||
if frontBytes+runeBytes[i] > availFront {
|
||||
break
|
||||
}
|
||||
frontBytes += runeBytes[i]
|
||||
frontRunes = append(frontRunes, runes[i])
|
||||
}
|
||||
|
||||
// 若前缀与尾部合并能覆盖全部 runes,则说明无需截断(理论上前面已判断过,但再验证一次)
|
||||
if len(frontRunes) == maxFrontCount {
|
||||
return name
|
||||
}
|
||||
|
||||
tailRunes := runes[n-tailSize:]
|
||||
ret = string(frontRunes) + string(tailRunes) + "-" + id + "-" + ext
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue