-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions #18084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
namespace Microsoft.Net.Http.Headers | ||
|
@@ -14,9 +15,9 @@ protected BaseHeaderParser(bool supportsMultipleValues) | |
|
||
protected abstract int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue); | ||
|
||
public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue) | ||
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNullWhen(false)]out T parsedValue) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like TryParseValue can return true even in cases where parsedValue is never set if SupportsMultipleValues is also true. |
||
{ | ||
parsedValue = default(T); | ||
parsedValue = default(T)!; | ||
|
||
// If multiple values are supported (i.e. list of values), then accept an empty string: The header may | ||
// be added multiple times to the request/response message. E.g. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,12 +31,12 @@ public class CacheControlHeaderValue | |
// Cache-Control headers, only one instance of CacheControlHeaderValue is created (if all headers contain valid | ||
// values, otherwise we may have multiple strings containing the invalid values). | ||
private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser | ||
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength); | ||
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength!); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This seems like something the tooling should be able to handle?
Or is the issue that T is unconstrained and could be a value type? |
||
|
||
private static readonly Action<StringSegment> CheckIsValidTokenAction = CheckIsValidToken; | ||
|
||
private bool _noCache; | ||
private ICollection<StringSegment> _noCacheHeaders; | ||
private ICollection<StringSegment>? _noCacheHeaders; | ||
private bool _noStore; | ||
private TimeSpan? _maxAge; | ||
private TimeSpan? _sharedMaxAge; | ||
|
@@ -47,10 +47,10 @@ private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser | |
private bool _onlyIfCached; | ||
private bool _public; | ||
private bool _private; | ||
private ICollection<StringSegment> _privateHeaders; | ||
private ICollection<StringSegment>? _privateHeaders; | ||
private bool _mustRevalidate; | ||
private bool _proxyRevalidate; | ||
private IList<NameValueHeaderValue> _extensions; | ||
private IList<NameValueHeaderValue>? _extensions; | ||
|
||
public CacheControlHeaderValue() | ||
{ | ||
|
@@ -240,7 +240,7 @@ public override string ToString() | |
return sb.ToString(); | ||
} | ||
|
||
public override bool Equals(object obj) | ||
public override bool Equals(object? obj) | ||
{ | ||
var other = obj as CacheControlHeaderValue; | ||
|
||
|
@@ -335,7 +335,7 @@ public static CacheControlHeaderValue Parse(StringSegment input) | |
return result; | ||
} | ||
|
||
public static bool TryParse(StringSegment input, out CacheControlHeaderValue parsedValue) | ||
public static bool TryParse(StringSegment input, out CacheControlHeaderValue? parsedValue) | ||
{ | ||
int index = 0; | ||
// Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null. | ||
|
@@ -347,7 +347,7 @@ public static bool TryParse(StringSegment input, out CacheControlHeaderValue par | |
return false; | ||
} | ||
|
||
private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue parsedValue) | ||
private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue? parsedValue) | ||
{ | ||
Contract.Requires(startIndex >= 0); | ||
|
||
|
@@ -361,11 +361,10 @@ private static int GetCacheControlLength(StringSegment input, int startIndex, ou | |
// Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an | ||
// instance of NameValueHeaderParser to parse the string. | ||
var current = startIndex; | ||
NameValueHeaderValue nameValue = null; | ||
var nameValueList = new List<NameValueHeaderValue>(); | ||
while (current < input.Length) | ||
{ | ||
if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out nameValue)) | ||
if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out var nameValue)) | ||
{ | ||
return 0; | ||
} | ||
|
@@ -539,11 +538,11 @@ private static bool TrySetTokenOnlyValue(NameValueHeaderValue nameValue, ref boo | |
private static bool TrySetOptionalTokenList( | ||
NameValueHeaderValue nameValue, | ||
ref bool boolField, | ||
ref ICollection<StringSegment> destination) | ||
ref ICollection<StringSegment>? destination) | ||
{ | ||
Contract.Requires(nameValue != null); | ||
|
||
if (nameValue.Value == null) | ||
if (nameValue!.Value == null) | ||
{ | ||
boolField = true; | ||
return true; | ||
|
@@ -605,7 +604,7 @@ private static bool TrySetTimeSpan(NameValueHeaderValue nameValue, ref TimeSpan? | |
{ | ||
Contract.Requires(nameValue != null); | ||
|
||
if (nameValue.Value == null) | ||
if (nameValue!.Value == null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The warning goes away if you remove Contract.Requires. These are redundant now and could be removed. |
||
{ | ||
return false; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
using System; | ||
using System.Buffers; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Diagnostics.Contracts; | ||
using System.Globalization; | ||
using System.Linq; | ||
|
@@ -26,10 +27,10 @@ public class ContentDispositionHeaderValue | |
private static readonly char[] SingleQuote = new char[] { '\'' }; | ||
|
||
private static readonly HttpHeaderParser<ContentDispositionHeaderValue> Parser | ||
= new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength); | ||
= new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength!); | ||
|
||
// Use list instead of dictionary since we may have multiple parameters with the same name. | ||
private ObjectCollection<NameValueHeaderValue> _parameters; | ||
private ObjectCollection<NameValueHeaderValue>? _parameters; | ||
private StringSegment _dispositionType; | ||
|
||
private ContentDispositionHeaderValue() | ||
|
@@ -128,7 +129,7 @@ public long? Size | |
// Remove parameter | ||
if (sizeParameter != null) | ||
{ | ||
_parameters.Remove(sizeParameter); | ||
_parameters!.Remove(sizeParameter); | ||
} | ||
} | ||
else if (value < 0) | ||
|
@@ -142,7 +143,7 @@ public long? Size | |
else | ||
{ | ||
string sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture); | ||
_parameters.Add(new NameValueHeaderValue(SizeString, sizeString)); | ||
_parameters!.Add(new NameValueHeaderValue(SizeString, sizeString)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an actual bug.
The fix would be to use |
||
} | ||
} | ||
} | ||
|
@@ -180,7 +181,7 @@ public override string ToString() | |
return _dispositionType + NameValueHeaderValue.ToString(_parameters, ';', true); | ||
} | ||
|
||
public override bool Equals(object obj) | ||
public override bool Equals(object? obj) | ||
{ | ||
var other = obj as ContentDispositionHeaderValue; | ||
|
||
|
@@ -205,13 +206,13 @@ public static ContentDispositionHeaderValue Parse(StringSegment input) | |
return Parser.ParseValue(input, ref index); | ||
} | ||
|
||
public static bool TryParse(StringSegment input, out ContentDispositionHeaderValue parsedValue) | ||
public static bool TryParse(StringSegment input, [NotNullWhen(true)]out ContentDispositionHeaderValue? parsedValue) | ||
{ | ||
var index = 0; | ||
return Parser.TryParseValue(input, ref index, out parsedValue); | ||
} | ||
|
||
private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue parsedValue) | ||
private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue? parsedValue) | ||
{ | ||
Contract.Requires(startIndex >= 0); | ||
|
||
|
@@ -318,7 +319,7 @@ private void SetDate(string parameter, DateTimeOffset? date) | |
// Remove parameter | ||
if (dateParameter != null) | ||
{ | ||
_parameters.Remove(dateParameter); | ||
_parameters!.Remove(dateParameter); | ||
} | ||
} | ||
else | ||
|
@@ -343,7 +344,7 @@ private StringSegment GetName(string parameter) | |
var nameParameter = NameValueHeaderValue.Find(_parameters, parameter); | ||
if (nameParameter != null) | ||
{ | ||
string result; | ||
string? result; | ||
// filename*=utf-8'lang'%7FMyString | ||
if (parameter.EndsWith("*", StringComparison.Ordinal)) | ||
{ | ||
|
@@ -375,7 +376,7 @@ private void SetName(StringSegment parameter, StringSegment value) | |
// Remove parameter | ||
if (nameParameter != null) | ||
{ | ||
_parameters.Remove(nameParameter); | ||
_parameters!.Remove(nameParameter); | ||
} | ||
} | ||
else | ||
|
@@ -497,7 +498,7 @@ private unsafe string EncodeMime(StringSegment input) | |
} | ||
|
||
// Attempt to decode MIME encoded strings | ||
private bool TryDecodeMime(StringSegment input, out string output) | ||
private bool TryDecodeMime(StringSegment input, [NotNullWhen(true)]out string? output) | ||
{ | ||
Contract.Assert(input != null); | ||
|
||
|
@@ -582,7 +583,7 @@ private static void HexEscape(StringBuilder builder, char c) | |
|
||
// Attempt to decode using RFC 5987 encoding. | ||
// encoding'language'my%20string | ||
private bool TryDecode5987(StringSegment input, out string output) | ||
private bool TryDecode5987(StringSegment input, [NotNullWhen(true)]out string? output) | ||
{ | ||
output = null; | ||
|
||
|
@@ -593,7 +594,7 @@ private bool TryDecode5987(StringSegment input, out string output) | |
} | ||
|
||
var decoded = new StringBuilder(); | ||
byte[] unescapedBytes = null; | ||
byte[]? unescapedBytes = null; | ||
try | ||
{ | ||
var encoding = Encoding.GetEncoding(parts[0].ToString()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I prefer a space here, though I'm willing to be overruled