OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [mime/] [multipart/] [multipart_test.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2010 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package multipart
6
 
7
import (
8
        "bytes"
9
        "encoding/json"
10
        "fmt"
11
        "io"
12
        "io/ioutil"
13
        "strings"
14
        "testing"
15
)
16
 
17
func TestHorizontalWhitespace(t *testing.T) {
18
        if !onlyHorizontalWhitespace([]byte(" \t")) {
19
                t.Error("expected pass")
20
        }
21
        if onlyHorizontalWhitespace([]byte("foo bar")) {
22
                t.Error("expected failure")
23
        }
24
}
25
 
26
func TestBoundaryLine(t *testing.T) {
27
        mr := NewReader(strings.NewReader(""), "myBoundary")
28
        if !mr.isBoundaryDelimiterLine([]byte("--myBoundary\r\n")) {
29
                t.Error("expected")
30
        }
31
        if !mr.isBoundaryDelimiterLine([]byte("--myBoundary \r\n")) {
32
                t.Error("expected")
33
        }
34
        if !mr.isBoundaryDelimiterLine([]byte("--myBoundary \n")) {
35
                t.Error("expected")
36
        }
37
        if mr.isBoundaryDelimiterLine([]byte("--myBoundary bogus \n")) {
38
                t.Error("expected fail")
39
        }
40
        if mr.isBoundaryDelimiterLine([]byte("--myBoundary bogus--")) {
41
                t.Error("expected fail")
42
        }
43
}
44
 
45
func escapeString(v string) string {
46
        bytes, _ := json.Marshal(v)
47
        return string(bytes)
48
}
49
 
50
func expectEq(t *testing.T, expected, actual, what string) {
51
        if expected == actual {
52
                return
53
        }
54
        t.Errorf("Unexpected value for %s; got %s (len %d) but expected: %s (len %d)",
55
                what, escapeString(actual), len(actual), escapeString(expected), len(expected))
56
}
57
 
58
func TestNameAccessors(t *testing.T) {
59
        tests := [...][3]string{
60
                {`form-data; name="foo"`, "foo", ""},
61
                {` form-data ; name=foo`, "foo", ""},
62
                {`FORM-DATA;name="foo"`, "foo", ""},
63
                {` FORM-DATA ; name="foo"`, "foo", ""},
64
                {` FORM-DATA ; name="foo"`, "foo", ""},
65
                {` FORM-DATA ; name=foo`, "foo", ""},
66
                {` FORM-DATA ; filename="foo.txt"; name=foo; baz=quux`, "foo", "foo.txt"},
67
                {` not-form-data ; filename="bar.txt"; name=foo; baz=quux`, "", "bar.txt"},
68
        }
69
        for i, test := range tests {
70
                p := &Part{Header: make(map[string][]string)}
71
                p.Header.Set("Content-Disposition", test[0])
72
                if g, e := p.FormName(), test[1]; g != e {
73
                        t.Errorf("test %d: FormName() = %q; want %q", i, g, e)
74
                }
75
                if g, e := p.FileName(), test[2]; g != e {
76
                        t.Errorf("test %d: FileName() = %q; want %q", i, g, e)
77
                }
78
        }
79
}
80
 
81
var longLine = strings.Repeat("\n\n\r\r\r\n\r\000", (1<<20)/8)
82
 
83
func testMultipartBody(sep string) string {
84
        testBody := `
85
This is a multi-part message.  This line is ignored.
86
--MyBoundary
87
Header1: value1
88
HEADER2: value2
89
foo-bar: baz
90
 
91
My value
92
The end.
93
--MyBoundary
94
name: bigsection
95
 
96
[longline]
97
--MyBoundary
98
Header1: value1b
99
HEADER2: value2b
100
foo-bar: bazb
101
 
102
Line 1
103
Line 2
104
Line 3 ends in a newline, but just one.
105
 
106
--MyBoundary
107
 
108
never read data
109
--MyBoundary--
110
 
111
 
112
useless trailer
113
`
114
        testBody = strings.Replace(testBody, "\n", sep, -1)
115
        return strings.Replace(testBody, "[longline]", longLine, 1)
116
}
117
 
118
func TestMultipart(t *testing.T) {
119
        bodyReader := strings.NewReader(testMultipartBody("\r\n"))
120
        testMultipart(t, bodyReader, false)
121
}
122
 
123
func TestMultipartOnlyNewlines(t *testing.T) {
124
        bodyReader := strings.NewReader(testMultipartBody("\n"))
125
        testMultipart(t, bodyReader, true)
126
}
127
 
128
func TestMultipartSlowInput(t *testing.T) {
129
        bodyReader := strings.NewReader(testMultipartBody("\r\n"))
130
        testMultipart(t, &slowReader{bodyReader}, false)
131
}
132
 
133
func testMultipart(t *testing.T, r io.Reader, onlyNewlines bool) {
134
        reader := NewReader(r, "MyBoundary")
135
        buf := new(bytes.Buffer)
136
 
137
        // Part1
138
        part, err := reader.NextPart()
139
        if part == nil || err != nil {
140
                t.Error("Expected part1")
141
                return
142
        }
143
        if x := part.Header.Get("Header1"); x != "value1" {
144
                t.Errorf("part.Header.Get(%q) = %q, want %q", "Header1", x, "value1")
145
        }
146
        if x := part.Header.Get("foo-bar"); x != "baz" {
147
                t.Errorf("part.Header.Get(%q) = %q, want %q", "foo-bar", x, "baz")
148
        }
149
        if x := part.Header.Get("Foo-Bar"); x != "baz" {
150
                t.Errorf("part.Header.Get(%q) = %q, want %q", "Foo-Bar", x, "baz")
151
        }
152
        buf.Reset()
153
        if _, err := io.Copy(buf, part); err != nil {
154
                t.Errorf("part 1 copy: %v", err)
155
        }
156
 
157
        adjustNewlines := func(s string) string {
158
                if onlyNewlines {
159
                        return strings.Replace(s, "\r\n", "\n", -1)
160
                }
161
                return s
162
        }
163
 
164
        expectEq(t, adjustNewlines("My value\r\nThe end."), buf.String(), "Value of first part")
165
 
166
        // Part2
167
        part, err = reader.NextPart()
168
        if err != nil {
169
                t.Fatalf("Expected part2; got: %v", err)
170
                return
171
        }
172
        if e, g := "bigsection", part.Header.Get("name"); e != g {
173
                t.Errorf("part2's name header: expected %q, got %q", e, g)
174
        }
175
        buf.Reset()
176
        if _, err := io.Copy(buf, part); err != nil {
177
                t.Errorf("part 2 copy: %v", err)
178
        }
179
        s := buf.String()
180
        if len(s) != len(longLine) {
181
                t.Errorf("part2 body expected long line of length %d; got length %d",
182
                        len(longLine), len(s))
183
        }
184
        if s != longLine {
185
                t.Errorf("part2 long body didn't match")
186
        }
187
 
188
        // Part3
189
        part, err = reader.NextPart()
190
        if part == nil || err != nil {
191
                t.Error("Expected part3")
192
                return
193
        }
194
        if part.Header.Get("foo-bar") != "bazb" {
195
                t.Error("Expected foo-bar: bazb")
196
        }
197
        buf.Reset()
198
        if _, err := io.Copy(buf, part); err != nil {
199
                t.Errorf("part 3 copy: %v", err)
200
        }
201
        expectEq(t, adjustNewlines("Line 1\r\nLine 2\r\nLine 3 ends in a newline, but just one.\r\n"),
202
                buf.String(), "body of part 3")
203
 
204
        // Part4
205
        part, err = reader.NextPart()
206
        if part == nil || err != nil {
207
                t.Error("Expected part 4 without errors")
208
                return
209
        }
210
 
211
        // Non-existent part5
212
        part, err = reader.NextPart()
213
        if part != nil {
214
                t.Error("Didn't expect a fifth part.")
215
        }
216
        if err != io.EOF {
217
                t.Errorf("On fifth part expected io.EOF; got %v", err)
218
        }
219
}
220
 
221
func TestVariousTextLineEndings(t *testing.T) {
222
        tests := [...]string{
223
                "Foo\nBar",
224
                "Foo\nBar\n",
225
                "Foo\r\nBar",
226
                "Foo\r\nBar\r\n",
227
                "Foo\rBar",
228
                "Foo\rBar\r",
229
                "\x00\x01\x02\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10",
230
        }
231
 
232
        for testNum, expectedBody := range tests {
233
                body := "--BOUNDARY\r\n" +
234
                        "Content-Disposition: form-data; name=\"value\"\r\n" +
235
                        "\r\n" +
236
                        expectedBody +
237
                        "\r\n--BOUNDARY--\r\n"
238
                bodyReader := strings.NewReader(body)
239
 
240
                reader := NewReader(bodyReader, "BOUNDARY")
241
                buf := new(bytes.Buffer)
242
                part, err := reader.NextPart()
243
                if part == nil {
244
                        t.Errorf("Expected a body part on text %d", testNum)
245
                        continue
246
                }
247
                if err != nil {
248
                        t.Errorf("Unexpected error on text %d: %v", testNum, err)
249
                        continue
250
                }
251
                written, err := io.Copy(buf, part)
252
                expectEq(t, expectedBody, buf.String(), fmt.Sprintf("test %d", testNum))
253
                if err != nil {
254
                        t.Errorf("Error copying multipart; bytes=%v, error=%v", written, err)
255
                }
256
 
257
                part, err = reader.NextPart()
258
                if part != nil {
259
                        t.Errorf("Unexpected part in test %d", testNum)
260
                }
261
                if err != io.EOF {
262
                        t.Errorf("On test %d expected io.EOF; got %v", testNum, err)
263
                }
264
 
265
        }
266
}
267
 
268
type maliciousReader struct {
269
        t *testing.T
270
        n int
271
}
272
 
273
const maxReadThreshold = 1 << 20
274
 
275
func (mr *maliciousReader) Read(b []byte) (n int, err error) {
276
        mr.n += len(b)
277
        if mr.n >= maxReadThreshold {
278
                mr.t.Fatal("too much was read")
279
                return 0, io.EOF
280
        }
281
        return len(b), nil
282
}
283
 
284
func TestLineLimit(t *testing.T) {
285
        mr := &maliciousReader{t: t}
286
        r := NewReader(mr, "fooBoundary")
287
        part, err := r.NextPart()
288
        if part != nil {
289
                t.Errorf("unexpected part read")
290
        }
291
        if err == nil {
292
                t.Errorf("expected an error")
293
        }
294
        if mr.n >= maxReadThreshold {
295
                t.Errorf("expected to read < %d bytes; read %d", maxReadThreshold, mr.n)
296
        }
297
}
298
 
299
func TestMultipartTruncated(t *testing.T) {
300
        testBody := `
301
This is a multi-part message.  This line is ignored.
302
--MyBoundary
303
foo-bar: baz
304
 
305
Oh no, premature EOF!
306
`
307
        body := strings.Replace(testBody, "\n", "\r\n", -1)
308
        bodyReader := strings.NewReader(body)
309
        r := NewReader(bodyReader, "MyBoundary")
310
 
311
        part, err := r.NextPart()
312
        if err != nil {
313
                t.Fatalf("didn't get a part")
314
        }
315
        _, err = io.Copy(ioutil.Discard, part)
316
        if err != io.ErrUnexpectedEOF {
317
                t.Fatalf("expected error io.ErrUnexpectedEOF; got %v", err)
318
        }
319
}
320
 
321
func TestZeroLengthBody(t *testing.T) {
322
        testBody := strings.Replace(`
323
This is a multi-part message.  This line is ignored.
324
--MyBoundary
325
foo: bar
326
 
327
 
328
--MyBoundary--
329
`, "\n", "\r\n", -1)
330
        r := NewReader(strings.NewReader(testBody), "MyBoundary")
331
        part, err := r.NextPart()
332
        if err != nil {
333
                t.Fatalf("didn't get a part")
334
        }
335
        n, err := io.Copy(ioutil.Discard, part)
336
        if err != nil {
337
                t.Errorf("error reading part: %v", err)
338
        }
339
        if n != 0 {
340
                t.Errorf("read %d bytes; expected 0", n)
341
        }
342
}
343
 
344
type slowReader struct {
345
        r io.Reader
346
}
347
 
348
func (s *slowReader) Read(p []byte) (int, error) {
349
        if len(p) == 0 {
350
                return s.r.Read(p)
351
        }
352
        return s.r.Read(p[:1])
353
}
354
 
355
func TestLineContinuation(t *testing.T) {
356
        // This body, extracted from an email, contains headers that span multiple
357
        // lines.
358
 
359
        // TODO: The original mail ended with a double-newline before the
360
        // final delimiter; this was manually edited to use a CRLF.
361
        testBody :=
362
                "\n--Apple-Mail-2-292336769\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain;\n\tcharset=US-ASCII;\n\tdelsp=yes;\n\tformat=flowed\n\nI'm finding the same thing happening on my system (10.4.1).\n\n\n--Apple-Mail-2-292336769\nContent-Transfer-Encoding: quoted-printable\nContent-Type: text/html;\n\tcharset=ISO-8859-1\n\nI'm finding the same thing =\nhappening on my system (10.4.1).=A0 But I built it with XCode =\n2.0.=\n\r\n--Apple-Mail-2-292336769--\n"
363
 
364
        r := NewReader(strings.NewReader(testBody), "Apple-Mail-2-292336769")
365
 
366
        for i := 0; i < 2; i++ {
367
                part, err := r.NextPart()
368
                if err != nil {
369
                        t.Fatalf("didn't get a part")
370
                }
371
                n, err := io.Copy(ioutil.Discard, part)
372
                if err != nil {
373
                        t.Errorf("error reading part: %v", err)
374
                }
375
                if n <= 0 {
376
                        t.Errorf("read %d bytes; expected >0", n)
377
                }
378
        }
379
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.