@@ -43,6 +43,19 @@ public class MultipartReaderTests
43
43
44
44
Content of a.txt.
45
45
46
+ --9051914041544843365972754266--
47
+ " ;
48
+ private const string TwoPartBodyWithUnicodeFileName =
49
+ @"--9051914041544843365972754266
50
+ Content-Disposition: form-data; name=""text""
51
+
52
+ text default
53
+ --9051914041544843365972754266
54
+ Content-Disposition: form-data; name=""file1""; filename=""a色.txt""
55
+ Content-Type: text/plain
56
+
57
+ Content of a.txt.
58
+
46
59
--9051914041544843365972754266--
47
60
" ;
48
61
private const string ThreePartBody =
@@ -147,6 +160,32 @@ public async Task MutipartReader_ReadTwoPartBody_Success()
147
160
Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
148
161
}
149
162
163
+ [ Fact ]
164
+ public async Task MutipartReader_ReadTwoPartBodyWithUnicodeFileName_Success ( )
165
+ {
166
+ var stream = MakeStream ( TwoPartBodyWithUnicodeFileName ) ;
167
+ var reader = new MultipartReader ( Boundary , stream ) ;
168
+
169
+ var section = await reader . ReadNextSectionAsync ( ) ;
170
+ Assert . NotNull ( section ) ;
171
+ Assert . Equal ( 1 , section . Headers . Count ) ;
172
+ Assert . Equal ( "form-data; name=\" text\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
173
+ var buffer = new MemoryStream ( ) ;
174
+ await section . Body . CopyToAsync ( buffer ) ;
175
+ Assert . Equal ( "text default" , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
176
+
177
+ section = await reader . ReadNextSectionAsync ( ) ;
178
+ Assert . NotNull ( section ) ;
179
+ Assert . Equal ( 2 , section . Headers . Count ) ;
180
+ Assert . Equal ( "form-data; name=\" file1\" ; filename=\" a色.txt\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
181
+ Assert . Equal ( "text/plain" , section . Headers [ "Content-Type" ] [ 0 ] ) ;
182
+ buffer = new MemoryStream ( ) ;
183
+ await section . Body . CopyToAsync ( buffer ) ;
184
+ Assert . Equal ( "Content of a.txt.\r \n " , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
185
+
186
+ Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
187
+ }
188
+
150
189
[ Fact ]
151
190
public async Task MutipartReader_ThreePartBody_Success ( )
152
191
{
@@ -181,5 +220,77 @@ public async Task MutipartReader_ThreePartBody_Success()
181
220
182
221
Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
183
222
}
223
+
224
+ [ Fact ]
225
+ public async Task MutipartReader_ReadInvalidUtf8Header_ReplacementCharacters ( )
226
+ {
227
+ var body1 =
228
+ @"--9051914041544843365972754266
229
+ Content-Disposition: form-data; name=""text"" filename=""a" ;
230
+
231
+ var body2 =
232
+ @".txt""
233
+
234
+ text default
235
+ --9051914041544843365972754266--
236
+ " ;
237
+ var stream = new MemoryStream ( ) ;
238
+ var bytes = Encoding . UTF8 . GetBytes ( body1 ) ;
239
+ stream . Write ( bytes , 0 , bytes . Length ) ;
240
+
241
+ // Write an invalid utf-8 segment in the middle
242
+ stream . Write ( new byte [ ] { 0xC1 , 0x21 } , 0 , 2 ) ;
243
+
244
+ bytes = Encoding . UTF8 . GetBytes ( body2 ) ;
245
+ stream . Write ( bytes , 0 , bytes . Length ) ;
246
+ stream . Seek ( 0 , SeekOrigin . Begin ) ;
247
+ var reader = new MultipartReader ( Boundary , stream ) ;
248
+
249
+ var section = await reader . ReadNextSectionAsync ( ) ;
250
+ Assert . NotNull ( section ) ;
251
+ Assert . Equal ( 1 , section . Headers . Count ) ;
252
+ Assert . Equal ( "form-data; name=\" text\" filename=\" a\uFFFD !.txt\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
253
+ var buffer = new MemoryStream ( ) ;
254
+ await section . Body . CopyToAsync ( buffer ) ;
255
+ Assert . Equal ( "text default" , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
256
+
257
+ Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
258
+ }
259
+
260
+ [ Fact ]
261
+ public async Task MutipartReader_ReadInvalidUtf8SurrogateHeader_ReplacementCharacters ( )
262
+ {
263
+ var body1 =
264
+ @"--9051914041544843365972754266
265
+ Content-Disposition: form-data; name=""text"" filename=""a" ;
266
+
267
+ var body2 =
268
+ @".txt""
269
+
270
+ text default
271
+ --9051914041544843365972754266--
272
+ " ;
273
+ var stream = new MemoryStream ( ) ;
274
+ var bytes = Encoding . UTF8 . GetBytes ( body1 ) ;
275
+ stream . Write ( bytes , 0 , bytes . Length ) ;
276
+
277
+ // Write an invalid utf-8 segment in the middle
278
+ stream . Write ( new byte [ ] { 0xED , 0xA0 , 85 } , 0 , 3 ) ;
279
+
280
+ bytes = Encoding . UTF8 . GetBytes ( body2 ) ;
281
+ stream . Write ( bytes , 0 , bytes . Length ) ;
282
+ stream . Seek ( 0 , SeekOrigin . Begin ) ;
283
+ var reader = new MultipartReader ( Boundary , stream ) ;
284
+
285
+ var section = await reader . ReadNextSectionAsync ( ) ;
286
+ Assert . NotNull ( section ) ;
287
+ Assert . Equal ( 1 , section . Headers . Count ) ;
288
+ Assert . Equal ( "form-data; name=\" text\" filename=\" a\uFFFD U.txt\" " , section . Headers [ "Content-Disposition" ] [ 0 ] ) ;
289
+ var buffer = new MemoryStream ( ) ;
290
+ await section . Body . CopyToAsync ( buffer ) ;
291
+ Assert . Equal ( "text default" , Encoding . ASCII . GetString ( buffer . ToArray ( ) ) ) ;
292
+
293
+ Assert . Null ( await reader . ReadNextSectionAsync ( ) ) ;
294
+ }
184
295
}
185
296
}
0 commit comments