Skip to content

Commit 3f3e304

Browse files
committed
Remove support for deprecated obs-fold in header values
1 parent d2e9f42 commit 3f3e304

File tree

5 files changed

+78
-119
lines changed

5 files changed

+78
-119
lines changed

src/libraries/System.Net.Http/src/Resources/Strings.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157
<value>Invalid range. At least one of the two parameters must not be null.</value>
158158
</data>
159159
<data name="net_http_headers_no_newlines" xml:space="preserve">
160-
<value>New-line characters in header values must be followed by a white-space character.</value>
160+
<value>New-line characters are not allowed in header values.</value>
161161
</data>
162162
<data name="net_http_content_buffersize_exceeded" xml:space="preserve">
163163
<value>Cannot write more bytes to the buffer than the configured maximum buffer size: {0}.</value>
@@ -217,7 +217,7 @@
217217
<value>The field cannot be longer than {0} characters.</value>
218218
</data>
219219
<data name="net_http_log_headers_no_newlines" xml:space="preserve">
220-
<value>Value for header '{0}' contains invalid new-line characters. Value: '{1}'.</value>
220+
<value>Value for header '{0}' contains new-line characters. Value: '{1}'.</value>
221221
</data>
222222
<data name="net_http_log_headers_invalid_quality" xml:space="preserve">
223223
<value>The 'q' value is invalid: '{0}'.</value>

src/libraries/System.Net.Http/src/System/Net/Http/Headers/GenericHeaderParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private static int ParseMultipleEntityTags(string value, int startIndex, out obj
119119
/// </summary>
120120
private static int ParseWithoutValidation(string value, int startIndex, out object? parsedValue)
121121
{
122-
if (HttpRuleParser.ContainsInvalidNewLine(value, startIndex))
122+
if (HttpRuleParser.ContainsNewLine(value, startIndex))
123123
{
124124
parsedValue = null;
125125
return 0;

src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ internal bool TryGetValues(HeaderDescriptor descriptor, [NotNullWhen(true)] out
221221
internal bool Contains(HeaderDescriptor descriptor)
222222
{
223223
// We can't just call headerStore.ContainsKey() since after parsing the value the header may not exist
224-
// anymore (if the value contains invalid newline chars, we remove the header). So try to parse the
224+
// anymore (if the value contains newline chars, we remove the header). So try to parse the
225225
// header value.
226226
return _headerStore != null && TryGetAndParseHeaderInfo(descriptor, out _);
227227
}
@@ -318,7 +318,7 @@ private IEnumerator<KeyValuePair<string, IEnumerable<string>>> GetEnumeratorCore
318318
// values.
319319
if (!ParseRawHeaderValues(descriptor, info, removeEmptyHeader: false))
320320
{
321-
// We have an invalid header value (contains invalid newline chars). Delete it.
321+
// We have an invalid header value (contains newline chars). Delete it.
322322
_headerStore.Remove(descriptor);
323323
}
324324
else
@@ -726,18 +726,17 @@ private bool ParseRawHeaderValues(HeaderDescriptor descriptor, HeaderStoreItemIn
726726
}
727727

728728
// At this point all values are either in info.ParsedValue, info.InvalidValue, or were removed since they
729-
// contain invalid newline chars. Reset RawValue.
729+
// contain newline chars. Reset RawValue.
730730
info.RawValue = null;
731731

732-
// During parsing, we removed the value since it contains invalid newline chars. Return false to indicate that
732+
// During parsing, we removed the value since it contains newline chars. Return false to indicate that
733733
// this is an empty header. If the caller specified to remove empty headers, we'll remove the header before
734734
// returning.
735735
if ((info.InvalidValue == null) && (info.ParsedValue == null))
736736
{
737737
if (removeEmptyHeader)
738738
{
739-
// After parsing the raw value, no value is left because all values contain invalid newline
740-
// chars.
739+
// After parsing the raw value, no value is left because all values contain newline chars.
741740
Debug.Assert(_headerStore != null);
742741
_headerStore.Remove(descriptor);
743742
}
@@ -754,7 +753,7 @@ private static void ParseMultipleRawHeaderValues(HeaderDescriptor descriptor, He
754753
{
755754
foreach (string rawValue in rawValues)
756755
{
757-
if (!ContainsInvalidNewLine(rawValue, descriptor.Name))
756+
if (!ContainsNewLine(rawValue, descriptor.Name))
758757
{
759758
AddParsedValue(info, rawValue);
760759
}
@@ -779,7 +778,7 @@ private static void ParseSingleRawHeaderValue(HeaderDescriptor descriptor, Heade
779778

780779
if (descriptor.Parser == null)
781780
{
782-
if (!ContainsInvalidNewLine(rawValue, descriptor.Name))
781+
if (!ContainsNewLine(rawValue, descriptor.Name))
783782
{
784783
AddParsedValue(info, rawValue);
785784
}
@@ -868,7 +867,7 @@ private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, He
868867
}
869868
else
870869
{
871-
if (!ContainsInvalidNewLine(value, descriptor.Name) && addWhenInvalid)
870+
if (!ContainsNewLine(value, descriptor.Name) && addWhenInvalid)
872871
{
873872
AddInvalidValue(info, value);
874873
}
@@ -885,7 +884,7 @@ private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, He
885884
}
886885

887886
Debug.Assert(value != null);
888-
if (!ContainsInvalidNewLine(value, descriptor.Name) && addWhenInvalid)
887+
if (!ContainsNewLine(value, descriptor.Name) && addWhenInvalid)
889888
{
890889
AddInvalidValue(info, value ?? string.Empty);
891890
}
@@ -973,8 +972,8 @@ private void ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreItemInfo i
973972
if (descriptor.Parser == null)
974973
{
975974
// If we don't have a parser for the header, we consider the value valid if it doesn't contains
976-
// invalid newline characters. We add the values as "parsed value". Note that we allow empty values.
977-
CheckInvalidNewLine(value);
975+
// newline characters. We add the values as "parsed value". Note that we allow empty values.
976+
CheckContainsNewLine(value);
978977
AddParsedValue(info, value ?? string.Empty);
979978
return;
980979
}
@@ -1077,22 +1076,22 @@ private bool TryGetHeaderDescriptor(string name, out HeaderDescriptor descriptor
10771076
return false;
10781077
}
10791078

1080-
private static void CheckInvalidNewLine(string? value)
1079+
private static void CheckContainsNewLine(string? value)
10811080
{
10821081
if (value == null)
10831082
{
10841083
return;
10851084
}
10861085

1087-
if (HttpRuleParser.ContainsInvalidNewLine(value))
1086+
if (HttpRuleParser.ContainsNewLine(value))
10881087
{
10891088
throw new FormatException(SR.net_http_headers_no_newlines);
10901089
}
10911090
}
10921091

1093-
private static bool ContainsInvalidNewLine(string value, string name)
1092+
private static bool ContainsNewLine(string value, string name)
10941093
{
1095-
if (HttpRuleParser.ContainsInvalidNewLine(value))
1094+
if (HttpRuleParser.ContainsNewLine(value))
10961095
{
10971096
if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, SR.Format(SR.net_http_log_headers_no_newlines, name, value));
10981097
return true;

src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -162,42 +162,9 @@ internal static int GetWhitespaceLength(string input, int startIndex)
162162
return input.Length - startIndex;
163163
}
164164

165-
internal static bool ContainsInvalidNewLine(string value)
165+
internal static bool ContainsNewLine(string value, int startIndex = 0)
166166
{
167-
return ContainsInvalidNewLine(value, 0);
168-
}
169-
170-
internal static bool ContainsInvalidNewLine(string value, int startIndex)
171-
{
172-
// Search for newlines followed by non-whitespace: This is not allowed in any header (be it a known or
173-
// custom header). E.g. "value\r\nbadformat: header" is invalid. However "value\r\n goodformat: header"
174-
// is valid: newlines followed by whitespace are allowed in header values.
175-
int current = startIndex;
176-
while (current < value.Length)
177-
{
178-
if (value[current] == '\r')
179-
{
180-
int char10Index = current + 1;
181-
if ((char10Index < value.Length) && (value[char10Index] == '\n'))
182-
{
183-
current = char10Index + 1;
184-
185-
if (current == value.Length)
186-
{
187-
return true; // We have a string terminating with \r\n. This is invalid.
188-
}
189-
190-
char c = value[current];
191-
if ((c != ' ') && (c != '\t'))
192-
{
193-
return true;
194-
}
195-
}
196-
}
197-
current++;
198-
}
199-
200-
return false;
167+
return value.AsSpan(startIndex).IndexOfAny('\r', '\n') != -1;
201168
}
202169

203170
internal static int GetNumberLength(string input, int startIndex, bool allowDecimal)

0 commit comments

Comments
 (0)