@@ -20,11 +20,22 @@ func newHeaderField(k, v string, b []byte) *headerField {
20
20
return & headerField {k : textproto .CanonicalMIMEHeaderKey (k ), v : v , b : b }
21
21
}
22
22
23
- func (f * headerField ) raw () []byte {
23
+ func (f * headerField ) raw () ( []byte , error ) {
24
24
if f .b != nil {
25
- return f .b
25
+ return f .b , nil
26
26
} else {
27
- return []byte (formatHeaderField (f .k , f .v ))
27
+ for pos , ch := range f .k {
28
+ // check if character is a printable US-ASCII except ':'
29
+ if ! (ch >= '!' && ch < ':' || ch > ':' && ch <= '~' ) {
30
+ return nil , fmt .Errorf ("field name contains incorrect symbols (\\ x%x at %v)" , ch , pos )
31
+ }
32
+ }
33
+
34
+ if pos := strings .IndexAny (f .v , "\r \n " ); pos != - 1 {
35
+ return nil , fmt .Errorf ("field value contains \\ r\\ n (at %v)" , pos )
36
+ }
37
+
38
+ return []byte (formatHeaderField (f .k , f .v )), nil
28
39
}
29
40
}
30
41
@@ -97,6 +108,9 @@ func (h *Header) AddRaw(kv []byte) {
97
108
98
109
// Add adds the key, value pair to the header. It prepends to any existing
99
110
// fields associated with key.
111
+ //
112
+ // Key and value should obey character requirements of RFC 6532.
113
+ // If you need to format/fold lines manually, use AddRaw
100
114
func (h * Header ) Add (k , v string ) {
101
115
k = textproto .CanonicalMIMEHeaderKey (k )
102
116
@@ -126,10 +140,12 @@ func (h *Header) Get(k string) string {
126
140
//
127
141
// The returned slice should not be modified and becomes invalid when the
128
142
// header is updated.
129
- func (h * Header ) Raw (k string ) []byte {
143
+ //
144
+ // Error is returned if header contains incorrect characters (RFC 6532)
145
+ func (h * Header ) Raw (k string ) ([]byte , error ) {
130
146
fields := h .m [textproto .CanonicalMIMEHeaderKey (k )]
131
147
if len (fields ) == 0 {
132
- return nil
148
+ return nil , nil
133
149
}
134
150
return fields [len (fields )- 1 ].raw ()
135
151
}
@@ -185,7 +201,7 @@ type HeaderFields interface {
185
201
// Value returns the value of the current field.
186
202
Value () string
187
203
// Raw returns the raw current header field. See Header.Raw.
188
- Raw () []byte
204
+ Raw () ( []byte , error )
189
205
// Del deletes the current field.
190
206
Del ()
191
207
// Len returns the amount of header fields in the subset of header iterated
@@ -228,7 +244,7 @@ func (fs *headerFields) Value() string {
228
244
return fs .field ().v
229
245
}
230
246
231
- func (fs * headerFields ) Raw () []byte {
247
+ func (fs * headerFields ) Raw () ( []byte , error ) {
232
248
return fs .field ().raw ()
233
249
}
234
250
@@ -298,7 +314,7 @@ func (fs *headerFieldsByKey) Value() string {
298
314
return fs .field ().v
299
315
}
300
316
301
- func (fs * headerFieldsByKey ) Raw () []byte {
317
+ func (fs * headerFieldsByKey ) Raw () ( []byte , error ) {
302
318
return fs .field ().raw ()
303
319
}
304
320
@@ -628,8 +644,12 @@ func formatHeaderField(k, v string) string {
628
644
func WriteHeader (w io.Writer , h Header ) error {
629
645
for i := len (h .l ) - 1 ; i >= 0 ; i -- {
630
646
f := h .l [i ]
631
- if _ , err := w .Write (f .raw ()); err != nil {
632
- return err
647
+ if rawField , err := f .raw (); err == nil {
648
+ if _ , err := w .Write (rawField ); err != nil {
649
+ return err
650
+ }
651
+ } else {
652
+ return fmt .Errorf ("failed to write header field #%v (%q): %w" , len (h .l )- i , f .k , err )
633
653
}
634
654
}
635
655
0 commit comments