@@ -4,22 +4,15 @@ import (
44 "bytes"
55 "io"
66 "io/fs"
7- stdpath "path"
87 "strings"
98
9+ "github.com/KirCute/zip"
1010 "github.com/OpenListTeam/OpenList/v4/internal/archive/tool"
11+ "github.com/OpenListTeam/OpenList/v4/internal/conf"
1112 "github.com/OpenListTeam/OpenList/v4/internal/errs"
13+ "github.com/OpenListTeam/OpenList/v4/internal/setting"
1214 "github.com/OpenListTeam/OpenList/v4/internal/stream"
13- "github.com/saintfish/chardet"
14- "github.com/yeka/zip"
15- "golang.org/x/text/encoding"
16- "golang.org/x/text/encoding/charmap"
17- "golang.org/x/text/encoding/japanese"
18- "golang.org/x/text/encoding/korean"
19- "golang.org/x/text/encoding/simplifiedchinese"
20- "golang.org/x/text/encoding/traditionalchinese"
21- "golang.org/x/text/encoding/unicode"
22- "golang.org/x/text/encoding/unicode/utf32"
15+ "golang.org/x/text/encoding/ianaindex"
2316 "golang.org/x/text/transform"
2417)
2518
@@ -37,22 +30,23 @@ func (r *WrapReader) Files() []tool.SubFile {
3730
3831type WrapFileInfo struct {
3932 fs.FileInfo
33+ efs bool
4034}
4135
4236func (f * WrapFileInfo ) Name () string {
43- return decodeName (f .FileInfo .Name ())
37+ return decodeName (f .FileInfo .Name (), f . efs )
4438}
4539
4640type WrapFile struct {
4741 f * zip.File
4842}
4943
5044func (f * WrapFile ) Name () string {
51- return decodeName (f .f .Name )
45+ return decodeName (f .f .Name , isEFS ( f . f . Flags ) )
5246}
5347
5448func (f * WrapFile ) FileInfo () fs.FileInfo {
55- return & WrapFileInfo {FileInfo : f .f .FileInfo ()}
49+ return & WrapFileInfo {FileInfo : f .f .FileInfo (), efs : isEFS ( f . f . Flags ) }
5650}
5751
5852func (f * WrapFile ) Open () (io.ReadCloser , error ) {
@@ -67,16 +61,33 @@ func (f *WrapFile) SetPassword(password string) {
6761 f .f .SetPassword (password )
6862}
6963
70- func getReader (ss []* stream.SeekableStream ) (* zip.Reader , error ) {
71- if len (ss ) > 1 && stdpath .Ext (ss [1 ].GetName ()) == ".z01" {
72- // FIXME: Incorrect parsing method for standard multipart zip format
73- ss = append (ss [1 :], ss [0 ])
74- }
75- reader , err := stream .NewMultiReaderAt (ss )
64+ func makePart (ss * stream.SeekableStream ) (zip.SizeReaderAt , error ) {
65+ ra , err := stream .NewReadAtSeeker (ss , 0 )
7666 if err != nil {
7767 return nil , err
7868 }
79- return zip .NewReader (reader , reader .Size ())
69+ return & inlineSizeReaderAt {ReaderAt : ra , size : ss .GetSize ()}, nil
70+ }
71+
72+ func (z * Zip ) getReader (ss []* stream.SeekableStream ) (* zip.Reader , error ) {
73+ if len (ss ) > 1 && z .traditionalSecondPartRegExp .MatchString (ss [1 ].GetName ()) {
74+ ss = append (ss [1 :], ss [0 ])
75+ ras := make ([]zip.SizeReaderAt , 0 , len (ss ))
76+ for _ , s := range ss {
77+ ra , err := makePart (s )
78+ if err != nil {
79+ return nil , err
80+ }
81+ ras = append (ras , ra )
82+ }
83+ return zip .NewMultipartReader (ras )
84+ } else {
85+ reader , err := stream .NewMultiReaderAt (ss )
86+ if err != nil {
87+ return nil , err
88+ }
89+ return zip .NewReader (reader , reader .Size ())
90+ }
8091}
8192
8293func filterPassword (err error ) error {
@@ -86,110 +97,29 @@ func filterPassword(err error) error {
8697 return err
8798}
8899
89- func decodeName (name string ) string {
90- b := []byte (name )
91- detector := chardet .NewTextDetector ()
92- results , err := detector .DetectAll (b )
93- if err != nil {
100+ func decodeName (name string , efs bool ) string {
101+ if efs {
94102 return name
95103 }
96- var ce , re , enc encoding.Encoding
97- for _ , r := range results {
98- if r .Confidence > 30 {
99- ce = getCommonEncoding (r .Charset )
100- if ce != nil {
101- break
102- }
103- }
104- if re == nil {
105- re = getEncoding (r .Charset )
106- }
107- }
108- if ce != nil {
109- enc = ce
110- } else if re != nil {
111- enc = re
112- } else {
104+ enc , err := ianaindex .IANA .Encoding (setting .GetStr (conf .NonEFSZipEncoding ))
105+ if err != nil {
113106 return name
114107 }
115- i := bytes .NewReader (b )
108+ i := bytes .NewReader ([] byte ( name ) )
116109 decoder := transform .NewReader (i , enc .NewDecoder ())
117110 content , _ := io .ReadAll (decoder )
118111 return string (content )
119112}
120113
121- func getCommonEncoding (name string ) (enc encoding.Encoding ) {
122- switch name {
123- case "UTF-8" :
124- enc = unicode .UTF8
125- case "UTF-16LE" :
126- enc = unicode .UTF16 (unicode .LittleEndian , unicode .IgnoreBOM )
127- case "Shift_JIS" :
128- enc = japanese .ShiftJIS
129- case "GB-18030" :
130- enc = simplifiedchinese .GB18030
131- case "EUC-KR" :
132- enc = korean .EUCKR
133- case "Big5" :
134- enc = traditionalchinese .Big5
135- default :
136- enc = nil
137- }
138- return
139- }
140-
141- func getEncoding (name string ) (enc encoding.Encoding ) {
142- switch name {
143- case "UTF-8" :
144- enc = unicode .UTF8
145- case "UTF-16BE" :
146- enc = unicode .UTF16 (unicode .BigEndian , unicode .IgnoreBOM )
147- case "UTF-16LE" :
148- enc = unicode .UTF16 (unicode .LittleEndian , unicode .IgnoreBOM )
149- case "UTF-32BE" :
150- enc = utf32 .UTF32 (utf32 .BigEndian , utf32 .IgnoreBOM )
151- case "UTF-32LE" :
152- enc = utf32 .UTF32 (utf32 .LittleEndian , utf32 .IgnoreBOM )
153- case "ISO-8859-1" :
154- enc = charmap .ISO8859_1
155- case "ISO-8859-2" :
156- enc = charmap .ISO8859_2
157- case "ISO-8859-3" :
158- enc = charmap .ISO8859_3
159- case "ISO-8859-4" :
160- enc = charmap .ISO8859_4
161- case "ISO-8859-5" :
162- enc = charmap .ISO8859_5
163- case "ISO-8859-6" :
164- enc = charmap .ISO8859_6
165- case "ISO-8859-7" :
166- enc = charmap .ISO8859_7
167- case "ISO-8859-8" :
168- enc = charmap .ISO8859_8
169- case "ISO-8859-8-I" :
170- enc = charmap .ISO8859_8I
171- case "ISO-8859-9" :
172- enc = charmap .ISO8859_9
173- case "windows-1251" :
174- enc = charmap .Windows1251
175- case "windows-1256" :
176- enc = charmap .Windows1256
177- case "KOI8-R" :
178- enc = charmap .KOI8R
179- case "Shift_JIS" :
180- enc = japanese .ShiftJIS
181- case "GB-18030" :
182- enc = simplifiedchinese .GB18030
183- case "EUC-JP" :
184- enc = japanese .EUCJP
185- case "EUC-KR" :
186- enc = korean .EUCKR
187- case "Big5" :
188- enc = traditionalchinese .Big5
189- case "ISO-2022-JP" :
190- enc = japanese .ISO2022JP
191- default :
192- enc = nil
193- }
194- return
114+ func isEFS (flags uint16 ) bool {
115+ return (flags & 0x800 ) > 0
116+ }
117+
118+ type inlineSizeReaderAt struct {
119+ io.ReaderAt
120+ size int64
121+ }
122+
123+ func (i * inlineSizeReaderAt ) Size () int64 {
124+ return i .size
195125}
0 commit comments