@@ -111,6 +111,7 @@ func (w *multipartWalker) nextFile() (Node, error) {
111
111
}, nil
112
112
}
113
113
114
+ // fileName returns a normalized filename from a part.
114
115
func fileName (part * multipart.Part ) string {
115
116
filename := part .FileName ()
116
117
if escaped , err := url .QueryUnescape (filename ); err == nil {
@@ -120,10 +121,32 @@ func fileName(part *multipart.Part) string {
120
121
return path .Clean ("/" + filename )
121
122
}
122
123
124
+ // dirName appends a slash to the end of the filename, if not present.
125
+ // expects a _cleaned_ path.
126
+ func dirName (filename string ) string {
127
+ if ! strings .HasSuffix (filename , "/" ) {
128
+ filename += "/"
129
+ }
130
+ return filename
131
+ }
132
+
133
+ // isDirectory checks if the media type is a valid directory media type.
123
134
func isDirectory (mediatype string ) bool {
124
135
return mediatype == multipartFormdataType || mediatype == applicationDirectory
125
136
}
126
137
138
+ // isChild checks if child is a child of parent directory.
139
+ // expects a _cleaned_ path.
140
+ func isChild (child , parent string ) bool {
141
+ return strings .HasPrefix (child , dirName (parent ))
142
+ }
143
+
144
+ // makeRelative makes the child path relative to the parent path.
145
+ // expects a _cleaned_ path.
146
+ func makeRelative (child , parent string ) string {
147
+ return strings .TrimPrefix (child , dirName (parent ))
148
+ }
149
+
127
150
type multipartIterator struct {
128
151
f * multipartDirectory
129
152
@@ -154,18 +177,18 @@ func (it *multipartIterator) Next() bool {
154
177
name := fileName (part )
155
178
156
179
// Is the file in a different directory?
157
- if ! strings . HasPrefix (name , it .f .path ) {
180
+ if ! isChild (name , it .f .path ) {
158
181
return false
159
182
}
160
183
161
184
// Have we already entered this directory?
162
- if it .curName != "" && strings . HasPrefix (name , path .Join (it .f .path , it .curName )) {
185
+ if it .curName != "" && isChild (name , path .Join (it .f .path , it .curName )) {
163
186
it .f .walker .consumePart ()
164
187
continue
165
188
}
166
189
167
190
// Make the path relative to the current directory.
168
- name = strings . TrimLeft (name [ len ( it .f .path ):], "/" )
191
+ name = makeRelative (name , it .f .path )
169
192
170
193
// Check if we need to create a fake directory (more than one
171
194
// path component).
0 commit comments