@@ -4021,6 +4021,18 @@ inline bool parse_header(const char *beg, const char *end, T fn) {
4021
4021
auto val = compare_case_ignore (key, " Location" )
4022
4022
? std::string (p, end)
4023
4023
: decode_url (std::string (p, end), false );
4024
+
4025
+ // NOTE: From RFC 9110:
4026
+ // Field values containing CR, LF, or NUL characters are
4027
+ // invalid and dangerous, due to the varying ways that
4028
+ // implementations might parse and interpret those
4029
+ // characters; a recipient of CR, LF, or NUL within a field
4030
+ // value MUST either reject the message or replace each of
4031
+ // those characters with SP before further processing or
4032
+ // forwarding of that message.
4033
+ static const std::string CR_LF_NUL (" \r\n\0 " , 3 );
4034
+ if (val.find_first_of (CR_LF_NUL) != std::string::npos) { return false ; }
4035
+
4024
4036
fn (key, val);
4025
4037
return true ;
4026
4038
}
@@ -4058,25 +4070,12 @@ inline bool read_headers(Stream &strm, Headers &headers) {
4058
4070
// Exclude line terminator
4059
4071
auto end = line_reader.ptr () + line_reader.size () - line_terminator_len;
4060
4072
4061
- parse_header (line_reader.ptr (), end,
4062
- [&](const std::string &key, std::string &val) {
4063
- // NOTE: From RFC 9110:
4064
- // Field values containing CR, LF, or NUL characters are
4065
- // invalid and dangerous, due to the varying ways that
4066
- // implementations might parse and interpret those
4067
- // characters; a recipient of CR, LF, or NUL within a field
4068
- // value MUST either reject the message or replace each of
4069
- // those characters with SP before further processing or
4070
- // forwarding of that message.
4071
- for (auto &c : val) {
4072
- switch (c) {
4073
- case ' \0 ' :
4074
- case ' \n ' :
4075
- case ' \r ' : c = ' ' ; break ;
4076
- }
4077
- }
4078
- headers.emplace (key, val);
4079
- });
4073
+ if (!parse_header (line_reader.ptr (), end,
4074
+ [&](const std::string &key, std::string &val) {
4075
+ headers.emplace (key, val);
4076
+ })) {
4077
+ return false ;
4078
+ }
4080
4079
}
4081
4080
4082
4081
return true ;
0 commit comments