Skip to content

Commit ce41587

Browse files
authored
feat(cloud189): Added sanitization for file and folder names (#9366)
- Introduced `sanitizeName` function to remove four-byte characters (e.g., emojis) from names before upload or creation. - Added `StripEmoji` option in driver configurations for cloud189 and cloud189pc. - Updated file and folder operations (upload, rename, and creation) to use sanitized names. - Ensured compatibility with both cloud189 and cloud189pc implementations.
1 parent 0cbc7eb commit ce41587

File tree

6 files changed

+88
-18
lines changed

6 files changed

+88
-18
lines changed

drivers/189/driver.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ func (d *Cloud189) Link(ctx context.Context, file model.Obj, args model.LinkArgs
8080
}
8181

8282
func (d *Cloud189) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
83+
safeName := d.sanitizeName(dirName)
8384
form := map[string]string{
8485
"parentFolderId": parentDir.GetID(),
85-
"folderName": dirName,
86+
"folderName": safeName,
8687
}
8788
_, err := d.request("https://cloud.189.cn/api/open/file/createFolder.action", http.MethodPost, func(req *resty.Request) {
8889
req.SetFormData(form)
@@ -126,9 +127,10 @@ func (d *Cloud189) Rename(ctx context.Context, srcObj model.Obj, newName string)
126127
idKey = "folderId"
127128
nameKey = "destFolderName"
128129
}
130+
safeName := d.sanitizeName(newName)
129131
form := map[string]string{
130132
idKey: srcObj.GetID(),
131-
nameKey: newName,
133+
nameKey: safeName,
132134
}
133135
_, err := d.request(url, http.MethodPost, func(req *resty.Request) {
134136
req.SetFormData(form)

drivers/189/meta.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
)
77

88
type Addition struct {
9-
Username string `json:"username" required:"true"`
10-
Password string `json:"password" required:"true"`
11-
Cookie string `json:"cookie" help:"Fill in the cookie if need captcha"`
9+
Username string `json:"username" required:"true"`
10+
Password string `json:"password" required:"true"`
11+
Cookie string `json:"cookie" help:"Fill in the cookie if need captcha"`
12+
StripEmoji bool `json:"strip_emoji" help:"Remove four-byte characters (e.g., emoji) before upload"`
1213
driver.RootID
1314
}
1415

drivers/189/util.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import (
1111
"io"
1212
"math"
1313
"net/http"
14+
"path"
1415
"strconv"
1516
"strings"
1617
"time"
18+
"unicode/utf8"
1719

1820
"github.com/alist-org/alist/v3/drivers/base"
1921
"github.com/alist-org/alist/v3/internal/driver"
@@ -222,13 +224,37 @@ func (d *Cloud189) getFiles(fileId string) ([]model.Obj, error) {
222224
return res, nil
223225
}
224226

227+
func (d *Cloud189) sanitizeName(name string) string {
228+
if !d.StripEmoji {
229+
return name
230+
}
231+
b := strings.Builder{}
232+
for _, r := range name {
233+
if utf8.RuneLen(r) == 4 {
234+
continue
235+
}
236+
b.WriteRune(r)
237+
}
238+
sanitized := b.String()
239+
if sanitized == "" {
240+
ext := path.Ext(name)
241+
if ext != "" {
242+
sanitized = "file" + ext
243+
} else {
244+
sanitized = "file"
245+
}
246+
}
247+
return sanitized
248+
}
249+
225250
func (d *Cloud189) oldUpload(dstDir model.Obj, file model.FileStreamer) error {
251+
safeName := d.sanitizeName(file.GetName())
226252
res, err := d.client.R().SetMultipartFormData(map[string]string{
227253
"parentId": dstDir.GetID(),
228254
"sessionKey": "??",
229255
"opertype": "1",
230-
"fname": file.GetName(),
231-
}).SetMultipartField("Filedata", file.GetName(), file.GetMimetype(), file).Post("https://hb02.upload.cloud.189.cn/v1/DCIWebUploadAction")
256+
"fname": safeName,
257+
}).SetMultipartField("Filedata", safeName, file.GetMimetype(), file).Post("https://hb02.upload.cloud.189.cn/v1/DCIWebUploadAction")
232258
if err != nil {
233259
return err
234260
}
@@ -313,9 +339,10 @@ func (d *Cloud189) newUpload(ctx context.Context, dstDir model.Obj, file model.F
313339
const DEFAULT int64 = 10485760
314340
var count = int64(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
315341

342+
safeName := d.sanitizeName(file.GetName())
316343
res, err := d.uploadRequest("/person/initMultiUpload", map[string]string{
317344
"parentFolderId": dstDir.GetID(),
318-
"fileName": encode(file.GetName()),
345+
"fileName": encode(safeName),
319346
"fileSize": strconv.FormatInt(file.GetSize(), 10),
320347
"sliceSize": strconv.FormatInt(DEFAULT, 10),
321348
"lazyCheck": "1",

drivers/189pc/driver.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,11 @@ func (y *Cloud189PC) MakeDir(ctx context.Context, parentDir model.Obj, dirName s
205205
fullUrl += "/createFolder.action"
206206

207207
var newFolder Cloud189Folder
208+
safeName := y.sanitizeName(dirName)
208209
_, err := y.post(fullUrl, func(req *resty.Request) {
209210
req.SetContext(ctx)
210211
req.SetQueryParams(map[string]string{
211-
"folderName": dirName,
212+
"folderName": safeName,
212213
"relativePath": "",
213214
})
214215
if isFamily {
@@ -225,6 +226,7 @@ func (y *Cloud189PC) MakeDir(ctx context.Context, parentDir model.Obj, dirName s
225226
if err != nil {
226227
return nil, err
227228
}
229+
newFolder.Name = safeName
228230
return &newFolder, nil
229231
}
230232

@@ -258,21 +260,29 @@ func (y *Cloud189PC) Rename(ctx context.Context, srcObj model.Obj, newName strin
258260
}
259261

260262
var newObj model.Obj
263+
safeName := y.sanitizeName(newName)
261264
switch f := srcObj.(type) {
262265
case *Cloud189File:
263266
fullUrl += "/renameFile.action"
264267
queryParam["fileId"] = srcObj.GetID()
265-
queryParam["destFileName"] = newName
268+
queryParam["destFileName"] = safeName
266269
newObj = &Cloud189File{Icon: f.Icon} // 复用预览
267270
case *Cloud189Folder:
268271
fullUrl += "/renameFolder.action"
269272
queryParam["folderId"] = srcObj.GetID()
270-
queryParam["destFolderName"] = newName
273+
queryParam["destFolderName"] = safeName
271274
newObj = &Cloud189Folder{}
272275
default:
273276
return nil, errs.NotSupport
274277
}
275278

279+
switch obj := newObj.(type) {
280+
case *Cloud189File:
281+
obj.Name = safeName
282+
case *Cloud189Folder:
283+
obj.Name = safeName
284+
}
285+
276286
_, err := y.request(fullUrl, method, func(req *resty.Request) {
277287
req.SetContext(ctx).SetQueryParams(queryParam)
278288
}, nil, newObj, isFamily)

drivers/189pc/meta.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
)
77

88
type Addition struct {
9-
Username string `json:"username" required:"true"`
10-
Password string `json:"password" required:"true"`
11-
VCode string `json:"validate_code"`
9+
Username string `json:"username" required:"true"`
10+
Password string `json:"password" required:"true"`
11+
VCode string `json:"validate_code"`
12+
StripEmoji bool `json:"strip_emoji" help:"Remove four-byte characters (e.g., emoji) before upload"`
1213
driver.RootID
1314
OrderBy string `json:"order_by" type:"select" options:"filename,filesize,lastOpTime" default:"filename"`
1415
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`

drivers/189pc/utils.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import (
1212
"net/http/cookiejar"
1313
"net/url"
1414
"os"
15+
"path"
1516
"regexp"
1617
"sort"
1718
"strconv"
1819
"strings"
1920
"time"
21+
"unicode/utf8"
2022

2123
"golang.org/x/sync/semaphore"
2224

@@ -57,6 +59,29 @@ const (
5759
CHANNEL_ID = "web_cloud.189.cn"
5860
)
5961

62+
func (y *Cloud189PC) sanitizeName(name string) string {
63+
if !y.StripEmoji {
64+
return name
65+
}
66+
b := strings.Builder{}
67+
for _, r := range name {
68+
if utf8.RuneLen(r) == 4 {
69+
continue
70+
}
71+
b.WriteRune(r)
72+
}
73+
sanitized := b.String()
74+
if sanitized == "" {
75+
ext := path.Ext(name)
76+
if ext != "" {
77+
sanitized = "file" + ext
78+
} else {
79+
sanitized = "file"
80+
}
81+
}
82+
return sanitized
83+
}
84+
6085
func (y *Cloud189PC) SignatureHeader(url, method, params string, isFamily bool) map[string]string {
6186
dateOfGmt := getHttpDateStr()
6287
sessionKey := y.getTokenInfo().SessionKey
@@ -475,10 +500,11 @@ func (y *Cloud189PC) refreshSession() (err error) {
475500
func (y *Cloud189PC) StreamUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress, isFamily bool, overwrite bool) (model.Obj, error) {
476501
size := file.GetSize()
477502
sliceSize := partSize(size)
503+
safeName := y.sanitizeName(file.GetName())
478504

479505
params := Params{
480506
"parentFolderId": dstDir.GetID(),
481-
"fileName": url.QueryEscape(file.GetName()),
507+
"fileName": url.QueryEscape(safeName),
482508
"fileSize": fmt.Sprint(file.GetSize()),
483509
"sliceSize": fmt.Sprint(sliceSize),
484510
"lazyCheck": "1",
@@ -596,7 +622,8 @@ func (y *Cloud189PC) RapidUpload(ctx context.Context, dstDir model.Obj, stream m
596622
return nil, errors.New("invalid hash")
597623
}
598624

599-
uploadInfo, err := y.OldUploadCreate(ctx, dstDir.GetID(), fileMd5, stream.GetName(), fmt.Sprint(stream.GetSize()), isFamily)
625+
safeName := y.sanitizeName(stream.GetName())
626+
uploadInfo, err := y.OldUploadCreate(ctx, dstDir.GetID(), fileMd5, safeName, fmt.Sprint(stream.GetSize()), isFamily)
600627
if err != nil {
601628
return nil, err
602629
}
@@ -615,6 +642,7 @@ func (y *Cloud189PC) FastUpload(ctx context.Context, dstDir model.Obj, file mode
615642
tmpF *os.File
616643
err error
617644
)
645+
safeName := y.sanitizeName(file.GetName())
618646
size := file.GetSize()
619647
if _, ok := cache.(io.ReaderAt); !ok && size > 0 {
620648
tmpF, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
@@ -697,7 +725,7 @@ func (y *Cloud189PC) FastUpload(ctx context.Context, dstDir model.Obj, file mode
697725
//step.2 预上传
698726
params := Params{
699727
"parentFolderId": dstDir.GetID(),
700-
"fileName": url.QueryEscape(file.GetName()),
728+
"fileName": url.QueryEscape(safeName),
701729
"fileSize": fmt.Sprint(file.GetSize()),
702730
"fileMd5": fileMd5Hex,
703731
"sliceSize": fmt.Sprint(sliceSize),
@@ -833,9 +861,10 @@ func (y *Cloud189PC) OldUpload(ctx context.Context, dstDir model.Obj, file model
833861
return nil, err
834862
}
835863
rateLimited := driver.NewLimitedUploadStream(ctx, io.NopCloser(tempFile))
864+
safeName := y.sanitizeName(file.GetName())
836865

837866
// 创建上传会话
838-
uploadInfo, err := y.OldUploadCreate(ctx, dstDir.GetID(), fileMd5, file.GetName(), fmt.Sprint(file.GetSize()), isFamily)
867+
uploadInfo, err := y.OldUploadCreate(ctx, dstDir.GetID(), fileMd5, safeName, fmt.Sprint(file.GetSize()), isFamily)
839868
if err != nil {
840869
return nil, err
841870
}

0 commit comments

Comments
 (0)