Add nullable to WebUtilities (#22543)

This commit is contained in:
Pranav K 2020-06-08 10:48:43 -07:00 committed by GitHub
parent aeb28d4b83
commit cd81d48766
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 154 additions and 140 deletions

View File

@ -2,6 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks> <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
<Nullable>annotations</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.WebUtilities.netcoreapp.cs" /> <Compile Include="Microsoft.AspNetCore.WebUtilities.netcoreapp.cs" />

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.WebUtilities
public bool InMemory { get { throw null; } } public bool InMemory { get { throw null; } }
public override long Length { get { throw null; } } public override long Length { get { throw null; } }
public override long Position { get { throw null; } set { } } public override long Position { get { throw null; } set { } }
public string TempFileName { get { throw null; } } public string? TempFileName { get { throw null; } }
protected override void Dispose(bool disposing) { } protected override void Dispose(bool disposing) { }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
public sealed partial class FileBufferingWriteStream : System.IO.Stream public sealed partial class FileBufferingWriteStream : System.IO.Stream
{ {
public FileBufferingWriteStream(int memoryThreshold = 32768, long? bufferLimit = default(long?), System.Func<string> tempFileDirectoryAccessor = null) { } public FileBufferingWriteStream(int memoryThreshold = 32768, long? bufferLimit = default(long?), System.Func<string>? tempFileDirectoryAccessor = null) { }
public override bool CanRead { get { throw null; } } public override bool CanRead { get { throw null; } }
public override bool CanSeek { get { throw null; } } public override bool CanSeek { get { throw null; } }
public override bool CanWrite { get { throw null; } } public override bool CanWrite { get { throw null; } }
@ -91,16 +91,16 @@ namespace Microsoft.AspNetCore.WebUtilities
public partial class FileMultipartSection public partial class FileMultipartSection
{ {
public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { } public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { }
public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue header) { } public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue? header) { }
public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.IO.Stream FileStream { get { throw null; } } public System.IO.Stream? FileStream { get { throw null; } }
public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
} }
public partial class FormMultipartSection public partial class FormMultipartSection
{ {
public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { } public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { }
public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue header) { } public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue? header) { }
public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.Threading.Tasks.Task<string> GetValueAsync() { throw null; } public System.Threading.Tasks.Task<string> GetValueAsync() { throw null; }
@ -149,9 +149,9 @@ namespace Microsoft.AspNetCore.WebUtilities
public override System.Threading.Tasks.Task<int> ReadAsync(char[] buffer, int index, int count) { throw null; } public override System.Threading.Tasks.Task<int> ReadAsync(char[] buffer, int index, int count) { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.ValueTask<int> ReadAsync(System.Memory<char> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.ValueTask<int> ReadAsync(System.Memory<char> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override string ReadLine() { throw null; } public override string? ReadLine() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.Task<string> ReadLineAsync() { throw null; } public override System.Threading.Tasks.Task<string?> ReadLineAsync() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.Task<string> ReadToEndAsync() { throw null; } public override System.Threading.Tasks.Task<string> ReadToEndAsync() { throw null; }
} }
@ -169,11 +169,11 @@ namespace Microsoft.AspNetCore.WebUtilities
public override void Write(char value) { } public override void Write(char value) { }
public override void Write(char[] values, int index, int count) { } public override void Write(char[] values, int index, int count) { }
public override void Write(System.ReadOnlySpan<char> value) { } public override void Write(System.ReadOnlySpan<char> value) { }
public override void Write(string value) { } public override void Write(string? value) { }
public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; } public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; }
public override System.Threading.Tasks.Task WriteAsync(char[] values, int index, int count) { throw null; } public override System.Threading.Tasks.Task WriteAsync(char[] values, int index, int count) { throw null; }
public override System.Threading.Tasks.Task WriteAsync(System.ReadOnlyMemory<char> value, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.Task WriteAsync(System.ReadOnlyMemory<char> value, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override System.Threading.Tasks.Task WriteAsync(string value) { throw null; } public override System.Threading.Tasks.Task WriteAsync(string? value) { throw null; }
public override void WriteLine(System.ReadOnlySpan<char> value) { } public override void WriteLine(System.ReadOnlySpan<char> value) { }
public override System.Threading.Tasks.Task WriteLineAsync(System.ReadOnlyMemory<char> value, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.Task WriteLineAsync(System.ReadOnlyMemory<char> value, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
} }
@ -198,22 +198,22 @@ namespace Microsoft.AspNetCore.WebUtilities
public int HeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int HeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public int HeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int HeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task<Microsoft.AspNetCore.WebUtilities.MultipartSection> ReadNextSectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.Threading.Tasks.Task<Microsoft.AspNetCore.WebUtilities.MultipartSection?> ReadNextSectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
} }
public partial class MultipartSection public partial class MultipartSection
{ {
public MultipartSection() { } public MultipartSection() { }
public long? BaseStreamOffset { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public long? BaseStreamOffset { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.IO.Stream? Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string ContentDisposition { get { throw null; } } public string? ContentDisposition { get { throw null; } }
public string ContentType { get { throw null; } } public string? ContentType { get { throw null; } }
public System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>? Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
} }
public static partial class MultipartSectionConverterExtensions public static partial class MultipartSectionConverterExtensions
{ {
public static Microsoft.AspNetCore.WebUtilities.FileMultipartSection AsFileSection(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; } public static Microsoft.AspNetCore.WebUtilities.FileMultipartSection? AsFileSection(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; }
public static Microsoft.AspNetCore.WebUtilities.FormMultipartSection AsFormDataSection(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; } public static Microsoft.AspNetCore.WebUtilities.FormMultipartSection? AsFormDataSection(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; }
public static Microsoft.Net.Http.Headers.ContentDispositionHeaderValue GetContentDispositionHeader(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; } public static Microsoft.Net.Http.Headers.ContentDispositionHeaderValue? GetContentDispositionHeader(this Microsoft.AspNetCore.WebUtilities.MultipartSection section) { throw null; }
} }
public static partial class MultipartSectionStreamExtensions public static partial class MultipartSectionStreamExtensions
{ {
@ -222,11 +222,11 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
public static partial class QueryHelpers public static partial class QueryHelpers
{ {
public static string AddQueryString(string uri, System.Collections.Generic.IDictionary<string, string> queryString) { throw null; } public static string AddQueryString(string uri, System.Collections.Generic.IDictionary<string, string?> queryString) { throw null; }
public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> queryString) { throw null; } public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> queryString) { throw null; }
public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> queryString) { throw null; } public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string?>> queryString) { throw null; }
public static string AddQueryString(string uri, string name, string value) { throw null; } public static string AddQueryString(string uri, string name, string value) { throw null; }
public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> ParseNullableQuery(string queryString) { throw null; } public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>? ParseNullableQuery(string queryString) { throw null; }
public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> ParseQuery(string queryString) { throw null; } public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> ParseQuery(string queryString) { throw null; }
} }
public static partial class ReasonPhrases public static partial class ReasonPhrases

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.IO; using System.IO;
@ -8,7 +10,7 @@ namespace Microsoft.AspNetCore.Internal
{ {
internal static class AspNetCoreTempDirectory internal static class AspNetCoreTempDirectory
{ {
private static string _tempDirectory; private static string? _tempDirectory;
public static string TempDirectory public static string TempDirectory
{ {

View File

@ -23,12 +23,12 @@ namespace Microsoft.AspNetCore.WebUtilities
private readonly ArrayPool<byte> _bytePool; private readonly ArrayPool<byte> _bytePool;
private readonly int _memoryThreshold; private readonly int _memoryThreshold;
private readonly long? _bufferLimit; private readonly long? _bufferLimit;
private string _tempFileDirectory; private string? _tempFileDirectory;
private readonly Func<string> _tempFileDirectoryAccessor; private readonly Func<string>? _tempFileDirectoryAccessor;
private string _tempFileName; private string? _tempFileName;
private Stream _buffer; private Stream _buffer;
private byte[] _rentedBuffer; private byte[]? _rentedBuffer;
private bool _inMemory = true; private bool _inMemory = true;
private bool _completelyBuffered; private bool _completelyBuffered;
@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.WebUtilities
get { return _inMemory; } get { return _inMemory; }
} }
public string TempFileName public string? TempFileName
{ {
get { return _tempFileName; } get { return _tempFileName; }
} }

View File

@ -4,9 +4,8 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.IO.Pipelines;
using System.Security.Cryptography;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.Internal;
@ -42,7 +41,7 @@ namespace Microsoft.AspNetCore.WebUtilities
public FileBufferingWriteStream( public FileBufferingWriteStream(
int memoryThreshold = DefaultMemoryThreshold, int memoryThreshold = DefaultMemoryThreshold,
long? bufferLimit = null, long? bufferLimit = null,
Func<string> tempFileDirectoryAccessor = null) Func<string>? tempFileDirectoryAccessor = null)
{ {
if (memoryThreshold < 0) if (memoryThreshold < 0)
{ {
@ -82,7 +81,7 @@ namespace Microsoft.AspNetCore.WebUtilities
internal PagedByteBuffer PagedByteBuffer { get; } internal PagedByteBuffer PagedByteBuffer { get; }
internal FileStream FileStream { get; private set; } internal FileStream? FileStream { get; private set; }
internal bool Disposed { get; private set; } internal bool Disposed { get; private set; }
@ -225,6 +224,7 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
[MemberNotNull(nameof(FileStream))]
private void EnsureFileStream() private void EnsureFileStream()
{ {
if (FileStream == null) if (FileStream == null)

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -29,9 +29,9 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="section">The section from which to create the <see cref="FileMultipartSection"/></param> /// <param name="section">The section from which to create the <see cref="FileMultipartSection"/></param>
/// <param name="header">An already parsed content disposition header</param> /// <param name="header">An already parsed content disposition header</param>
public FileMultipartSection(MultipartSection section, ContentDispositionHeaderValue header) public FileMultipartSection(MultipartSection section, ContentDispositionHeaderValue? header)
{ {
if (!header.IsFileDisposition()) if (header is null || !header.IsFileDisposition())
{ {
throw new ArgumentException($"Argument must be a file section", nameof(section)); throw new ArgumentException($"Argument must be a file section", nameof(section));
} }
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// <summary> /// <summary>
/// Gets the file stream from the section body /// Gets the file stream from the section body
/// </summary> /// </summary>
public Stream FileStream => Section.Body; public Stream? FileStream => Section.Body;
/// <summary> /// <summary>
/// Gets the name of the section /// Gets the name of the section

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="section">The section from which to create the <see cref="FormMultipartSection"/></param> /// <param name="section">The section from which to create the <see cref="FormMultipartSection"/></param>
/// <param name="header">An already parsed content disposition header</param> /// <param name="header">An already parsed content disposition header</param>
public FormMultipartSection(MultipartSection section, ContentDispositionHeaderValue header) public FormMultipartSection(MultipartSection section, ContentDispositionHeaderValue? header)
{ {
if (header == null || !header.IsFormDisposition()) if (header == null || !header.IsFormDisposition())
{ {

View File

@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.WebUtilities
private static ReadOnlySpan<byte> UTF8AndEncoded => new byte[] { (byte)'&' }; private static ReadOnlySpan<byte> UTF8AndEncoded => new byte[] { (byte)'&' };
// Used for other encodings // Used for other encodings
private byte[] _otherEqualEncoding; private byte[]? _otherEqualEncoding;
private byte[] _otherAndEncoding; private byte[]? _otherAndEncoding;
private readonly PipeReader _pipeReader; private readonly PipeReader _pipeReader;
private readonly Encoding _encoding; private readonly Encoding _encoding;

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -28,8 +29,8 @@ namespace Microsoft.AspNetCore.WebUtilities
private readonly StringBuilder _builder = new StringBuilder(); private readonly StringBuilder _builder = new StringBuilder();
private int _bufferOffset; private int _bufferOffset;
private int _bufferCount; private int _bufferCount;
private string _currentKey; private string? _currentKey;
private string _currentValue; private string? _currentValue;
private bool _endOfStream; private bool _endOfStream;
private bool _disposed; private bool _disposed;
@ -189,7 +190,7 @@ namespace Microsoft.AspNetCore.WebUtilities
return true; return true;
} }
private bool TryReadWord(char separator, int limit, out string value) private bool TryReadWord(char separator, int limit, [NotNullWhen(true)] out string? value)
{ {
do do
{ {
@ -201,7 +202,7 @@ namespace Microsoft.AspNetCore.WebUtilities
return false; return false;
} }
private bool ReadChar(char separator, int limit, out string word) private bool ReadChar(char separator, int limit, [NotNullWhen(true)] out string? word)
{ {
// End // End
if (_bufferCount == 0) if (_bufferCount == 0)
@ -283,6 +284,7 @@ namespace Microsoft.AspNetCore.WebUtilities
return accumulator.GetResults(); return accumulator.GetResults();
} }
[MemberNotNullWhen(true, nameof(_currentKey), nameof(_currentValue))]
private bool ReadSucceeded() private bool ReadSucceeded()
{ {
return _currentKey != null && _currentValue != null; return _currentKey != null && _currentValue != null;

View File

@ -328,14 +328,14 @@ namespace Microsoft.AspNetCore.WebUtilities
return charsRead; return charsRead;
} }
public override async Task<string> ReadLineAsync() public override async Task<string?> ReadLineAsync()
{ {
if (_disposed) if (_disposed)
{ {
throw new ObjectDisposedException(nameof(HttpRequestStreamReader)); throw new ObjectDisposedException(nameof(HttpRequestStreamReader));
} }
StringBuilder sb = null; StringBuilder? sb = null;
var consumeLineFeed = false; var consumeLineFeed = false;
while (true) while (true)
@ -365,14 +365,14 @@ namespace Microsoft.AspNetCore.WebUtilities
// immediately followed by a line feed. The resulting string does not // immediately followed by a line feed. The resulting string does not
// contain the terminating carriage return and/or line feed. The returned // contain the terminating carriage return and/or line feed. The returned
// value is null if the end of the input stream has been reached. // value is null if the end of the input stream has been reached.
public override string ReadLine() public override string? ReadLine()
{ {
if (_disposed) if (_disposed)
{ {
throw new ObjectDisposedException(nameof(HttpRequestStreamReader)); throw new ObjectDisposedException(nameof(HttpRequestStreamReader));
} }
StringBuilder sb = null; StringBuilder? sb = null;
var consumeLineFeed = false; var consumeLineFeed = false;
while (true) while (true)
@ -395,7 +395,7 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
private ReadLineStepResult ReadLineStep(ref StringBuilder sb, ref bool consumeLineFeed) private ReadLineStepResult ReadLineStep(ref StringBuilder? sb, ref bool consumeLineFeed)
{ {
const char carriageReturn = '\r'; const char carriageReturn = '\r';
const char lineFeed = '\n'; const char lineFeed = '\n';
@ -549,14 +549,14 @@ namespace Microsoft.AspNetCore.WebUtilities
public static ReadLineStepResult FromResult(string value) => new ReadLineStepResult(true, value); public static ReadLineStepResult FromResult(string value) => new ReadLineStepResult(true, value);
private ReadLineStepResult(bool completed, string result) private ReadLineStepResult(bool completed, string? result)
{ {
Completed = completed; Completed = completed;
Result = result; Result = result;
} }
public bool Completed { get; } public bool Completed { get; }
public string Result { get; } public string? Result { get; }
} }
} }
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Buffers; using System.Buffers;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -150,7 +151,7 @@ namespace Microsoft.AspNetCore.WebUtilities
}; };
} }
public override void Write(string value) public override void Write(string? value)
{ {
if (_disposed) if (_disposed)
{ {
@ -257,21 +258,20 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
public override Task WriteAsync(string value) public override Task WriteAsync(string? value)
{ {
if (_disposed) if (_disposed)
{ {
return GetObjectDisposedTask(); return GetObjectDisposedTask();
} }
var count = value?.Length ?? 0; if (string.IsNullOrEmpty(value))
if (count == 0)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
var remaining = _charBufferSize - _charBufferCount; var remaining = _charBufferSize - _charBufferCount;
if (remaining >= count) if (remaining >= value.Length)
{ {
// Enough room in buffer, no need to go async // Enough room in buffer, no need to go async
CopyToCharBuffer(value); CopyToCharBuffer(value);

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Description>ASP.NET Core utilities, such as for working with forms, multipart messages, and query strings.</Description> <Description>ASP.NET Core utilities, such as for working with forms, multipart messages, and query strings.</Description>
@ -9,6 +9,8 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore</PackageTags> <PackageTags>aspnetcore</PackageTags>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<LangVersion>Preview</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
public byte[] BoundaryBytes { get; private set; } public byte[] BoundaryBytes { get; private set; } = default!; // This gets initialized as part of Initialize called from in the ctor.
public int FinalBoundaryLength { get; private set; } public int FinalBoundaryLength { get; private set; }
} }

View File

@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
public long? BodyLengthLimit { get; set; } public long? BodyLengthLimit { get; set; }
public async Task<MultipartSection> ReadNextSectionAsync(CancellationToken cancellationToken = new CancellationToken()) public async Task<MultipartSection?> ReadNextSectionAsync(CancellationToken cancellationToken = new CancellationToken())
{ {
// Drain the prior section. // Drain the prior section.
await _currentStream.DrainAsync(cancellationToken); await _currentStream.DrainAsync(cancellationToken);
@ -115,4 +115,4 @@ namespace Microsoft.AspNetCore.WebUtilities
return accumulator.GetResults(); return accumulator.GetResults();
} }
} }
} }

View File

@ -239,7 +239,7 @@ namespace Microsoft.AspNetCore.WebUtilities
return UpdatePosition(read); return UpdatePosition(read);
} }
var length = _boundary.BoundaryBytes.Length; var length = _boundary.BoundaryBytes!.Length;
Debug.Assert(matchCount == length); Debug.Assert(matchCount == length);
// "The boundary may be followed by zero or more characters of // "The boundary may be followed by zero or more characters of
@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.WebUtilities
matchOffset = segment1.Offset; matchOffset = segment1.Offset;
while (matchOffset < segmentEndMinusMatchBytesLength) while (matchOffset < segmentEndMinusMatchBytesLength)
{ {
var lookaheadTailChar = segment1.Array[matchOffset + matchBytesLengthMinusOne]; var lookaheadTailChar = segment1.Array![matchOffset + matchBytesLengthMinusOne];
if (lookaheadTailChar == matchBytesLastByte && if (lookaheadTailChar == matchBytesLastByte &&
CompareBuffers(segment1.Array, matchOffset, matchBytes, 0, matchBytesLengthMinusOne) == 0) CompareBuffers(segment1.Array, matchOffset, matchBytes, 0, matchBytesLengthMinusOne) == 0)
{ {
@ -307,7 +307,7 @@ namespace Microsoft.AspNetCore.WebUtilities
var countLimit = segmentEnd - matchOffset; var countLimit = segmentEnd - matchOffset;
for (matchCount = 0; matchCount < matchBytes.Length && matchCount < countLimit; matchCount++) for (matchCount = 0; matchCount < matchBytes.Length && matchCount < countLimit; matchCount++)
{ {
if (matchBytes[matchCount] != segment1.Array[matchOffset + matchCount]) if (matchBytes[matchCount] != segment1.Array![matchOffset + matchCount])
{ {
matchCount = 0; matchCount = 0;
break; break;

View File

@ -10,12 +10,11 @@ namespace Microsoft.AspNetCore.WebUtilities
{ {
public class MultipartSection public class MultipartSection
{ {
public string ContentType public string? ContentType
{ {
get get
{ {
StringValues values; if (Headers != null && Headers.TryGetValue(HeaderNames.ContentType, out var values))
if (Headers.TryGetValue(HeaderNames.ContentType, out values))
{ {
return values; return values;
} }
@ -23,12 +22,11 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
public string ContentDisposition public string? ContentDisposition
{ {
get get
{ {
StringValues values; if (Headers != null && Headers.TryGetValue(HeaderNames.ContentDisposition, out var values))
if (Headers.TryGetValue(HeaderNames.ContentDisposition, out values))
{ {
return values; return values;
} }
@ -36,9 +34,9 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
public Dictionary<string, StringValues> Headers { get; set; } public Dictionary<string, StringValues>? Headers { get; set; }
public Stream Body { get; set; } public Stream? Body { get; set; }
/// <summary> /// <summary>
/// The position where the body starts in the total multipart body. /// The position where the body starts in the total multipart body.

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="section">The section to convert</param> /// <param name="section">The section to convert</param>
/// <returns>A file section</returns> /// <returns>A file section</returns>
public static FileMultipartSection AsFileSection(this MultipartSection section) public static FileMultipartSection? AsFileSection(this MultipartSection section)
{ {
if (section == null) if (section == null)
{ {
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="section">The section to convert</param> /// <param name="section">The section to convert</param>
/// <returns>A form section</returns> /// <returns>A form section</returns>
public static FormMultipartSection AsFormDataSection(this MultipartSection section) public static FormMultipartSection? AsFormDataSection(this MultipartSection section)
{ {
if (section == null) if (section == null)
{ {
@ -60,10 +60,9 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="section">The section from which to retrieve</param> /// <param name="section">The section from which to retrieve</param>
/// <returns>A <see cref="ContentDispositionHeaderValue"/> if the header was found, null otherwise</returns> /// <returns>A <see cref="ContentDispositionHeaderValue"/> if the header was found, null otherwise</returns>
public static ContentDispositionHeaderValue GetContentDispositionHeader(this MultipartSection section) public static ContentDispositionHeaderValue? GetContentDispositionHeader(this MultipartSection section)
{ {
ContentDispositionHeaderValue header; if (!ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var header))
if (!ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out header))
{ {
return null; return null;
} }

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -26,10 +26,14 @@ namespace Microsoft.AspNetCore.WebUtilities
throw new ArgumentNullException(nameof(section)); throw new ArgumentNullException(nameof(section));
} }
MediaTypeHeaderValue sectionMediaType; if (section.Body is null)
MediaTypeHeaderValue.TryParse(section.ContentType, out sectionMediaType); {
throw new ArgumentException($"Multipart section must have a body to be read.", nameof(section));
}
Encoding streamEncoding = sectionMediaType?.Encoding; MediaTypeHeaderValue.TryParse(section.ContentType, out var sectionMediaType);
var streamEncoding = sectionMediaType?.Encoding;
if (streamEncoding == null || streamEncoding == Encoding.UTF7) if (streamEncoding == null || streamEncoding == Encoding.UTF7)
{ {
streamEncoding = Encoding.UTF8; streamEncoding = Encoding.UTF8;

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.WebUtilities
{ {
internal const int PageSize = 1024; internal const int PageSize = 1024;
private readonly ArrayPool<byte> _arrayPool; private readonly ArrayPool<byte> _arrayPool;
private byte[] _currentPage; private byte[]? _currentPage;
private int _currentPageIndex; private int _currentPageIndex;
public PagedByteBuffer(ArrayPool<byte> arrayPool) public PagedByteBuffer(ArrayPool<byte> arrayPool)

View File

@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
return AddQueryString( return AddQueryString(
uri, new[] { new KeyValuePair<string, string>(name, value) }); uri, new[] { new KeyValuePair<string, string?>(name, value) });
} }
/// <summary> /// <summary>
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// <returns>The combined result.</returns> /// <returns>The combined result.</returns>
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
public static string AddQueryString(string uri, IDictionary<string, string> queryString) public static string AddQueryString(string uri, IDictionary<string, string?> queryString)
{ {
if (uri == null) if (uri == null)
{ {
@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.WebUtilities
throw new ArgumentNullException(nameof(queryString)); throw new ArgumentNullException(nameof(queryString));
} }
return AddQueryString(uri, (IEnumerable<KeyValuePair<string, string>>)queryString); return AddQueryString(uri, (IEnumerable<KeyValuePair<string, string?>>)queryString);
} }
/// <summary> /// <summary>
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.WebUtilities
throw new ArgumentNullException(nameof(queryString)); throw new ArgumentNullException(nameof(queryString));
} }
return AddQueryString(uri, queryString.SelectMany(kvp => kvp.Value, (kvp, v) => KeyValuePair.Create(kvp.Key, v))); return AddQueryString(uri, queryString.SelectMany(kvp => kvp.Value, (kvp, v) => KeyValuePair.Create<string, string?>(kvp.Key, v)));
} }
/// <summary> /// <summary>
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
public static string AddQueryString( public static string AddQueryString(
string uri, string uri,
IEnumerable<KeyValuePair<string, string>> queryString) IEnumerable<KeyValuePair<string, string?>> queryString)
{ {
if (uri == null) if (uri == null)
{ {
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.WebUtilities
/// </summary> /// </summary>
/// <param name="queryString">The raw query string value, with or without the leading '?'.</param> /// <param name="queryString">The raw query string value, with or without the leading '?'.</param>
/// <returns>A collection of parsed keys and values, null if there are no entries.</returns> /// <returns>A collection of parsed keys and values, null if there are no entries.</returns>
public static Dictionary<string, StringValues> ParseNullableQuery(string queryString) public static Dictionary<string, StringValues>? ParseNullableQuery(string queryString)
{ {
var accumulator = new KeyValueAccumulator(); var accumulator = new KeyValueAccumulator();

View File

@ -80,8 +80,7 @@ namespace Microsoft.AspNetCore.WebUtilities
public static string GetReasonPhrase(int statusCode) public static string GetReasonPhrase(int statusCode)
{ {
string phrase; return Phrases.TryGetValue(statusCode, out var phrase) ? phrase : string.Empty;
return Phrases.TryGetValue(statusCode, out phrase) ? phrase : string.Empty;
} }
} }
} }

View File

@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.Equal(read0 + read1, stream.Position); Assert.Equal(read0 + read1, stream.Position);
Assert.False(stream.InMemory); Assert.False(stream.InMemory);
Assert.NotNull(stream.TempFileName); Assert.NotNull(stream.TempFileName);
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
Assert.True(File.Exists(tempFileName)); Assert.True(File.Exists(tempFileName));
var read2 = stream.Read(bytes, 0, bytes.Length); var read2 = stream.Read(bytes, 0, bytes.Length);
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.Equal(read0 + read1, stream.Position); Assert.Equal(read0 + read1, stream.Position);
Assert.False(stream.InMemory); Assert.False(stream.InMemory);
Assert.NotNull(stream.TempFileName); Assert.NotNull(stream.TempFileName);
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
Assert.True(File.Exists(tempFileName)); Assert.True(File.Exists(tempFileName));
var exception = Assert.Throws<IOException>(() => stream.Read(bytes, 0, bytes.Length)); var exception = Assert.Throws<IOException>(() => stream.Read(bytes, 0, bytes.Length));
@ -219,7 +219,7 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.Equal(read0 + read1, stream.Position); Assert.Equal(read0 + read1, stream.Position);
Assert.False(stream.InMemory); Assert.False(stream.InMemory);
Assert.NotNull(stream.TempFileName); Assert.NotNull(stream.TempFileName);
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
Assert.True(File.Exists(tempFileName)); Assert.True(File.Exists(tempFileName));
var read2 = await stream.ReadAsync(bytes, 0, bytes.Length); var read2 = await stream.ReadAsync(bytes, 0, bytes.Length);
@ -280,7 +280,7 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.Equal(read0 + read1, stream.Position); Assert.Equal(read0 + read1, stream.Position);
Assert.False(stream.InMemory); Assert.False(stream.InMemory);
Assert.NotNull(stream.TempFileName); Assert.NotNull(stream.TempFileName);
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
Assert.True(File.Exists(tempFileName)); Assert.True(File.Exists(tempFileName));
var exception = await Assert.ThrowsAsync<IOException>(() => stream.ReadAsync(bytes, 0, bytes.Length)); var exception = await Assert.ThrowsAsync<IOException>(() => stream.ReadAsync(bytes, 0, bytes.Length));
@ -313,7 +313,7 @@ namespace Microsoft.AspNetCore.WebUtilities
stream.Read(new byte[4]); stream.Read(new byte[4]);
Assert.True(File.Exists(stream.TempFileName), "tempFile should be created"); Assert.True(File.Exists(stream.TempFileName), "tempFile should be created");
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
arrayPool.Verify(v => v.Rent(It.IsAny<int>()), Times.Once()); arrayPool.Verify(v => v.Rent(It.IsAny<int>()), Times.Once());
arrayPool.Verify(v => v.Return(It.IsAny<byte[]>(), It.IsAny<bool>()), Times.Once()); arrayPool.Verify(v => v.Return(It.IsAny<byte[]>(), It.IsAny<bool>()), Times.Once());
@ -342,7 +342,7 @@ namespace Microsoft.AspNetCore.WebUtilities
await stream.ReadAsync(new byte[4]); await stream.ReadAsync(new byte[4]);
Assert.True(File.Exists(stream.TempFileName), "tempFile should be created"); Assert.True(File.Exists(stream.TempFileName), "tempFile should be created");
tempFileName = stream.TempFileName; tempFileName = stream.TempFileName!;
arrayPool.Verify(v => v.Rent(It.IsAny<int>()), Times.Once()); arrayPool.Verify(v => v.Rent(It.IsAny<int>()), Times.Once());
arrayPool.Verify(v => v.Return(It.IsAny<byte[]>(), It.IsAny<bool>()), Times.Once()); arrayPool.Verify(v => v.Return(It.IsAny<byte[]>(), It.IsAny<bool>()), Times.Once());

View File

@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(input, fileBytes); Assert.Equal(input, fileBytes);
// No content should be in the memory stream // No content should be in the memory stream
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(input, fileBytes); Assert.Equal(input, fileBytes);
// No content should be in the memory stream // No content should be in the memory stream
@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(new byte[] { 1, 2, 3, 4, 5, }, fileBytes); Assert.Equal(new byte[] { 1, 2, 3, 4, 5, }, fileBytes);
Assert.Equal(new byte[] { 6, 7 }, ReadBufferedContent(pageBuffer)); Assert.Equal(new byte[] { 6, 7 }, ReadBufferedContent(pageBuffer));
@ -194,7 +194,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(input, fileBytes); Assert.Equal(input, fileBytes);
// No content should be in the memory stream // No content should be in the memory stream
@ -217,7 +217,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(input, fileBytes); Assert.Equal(input, fileBytes);
// No content should be in the memory stream // No content should be in the memory stream
@ -241,7 +241,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// File should have been created. // File should have been created.
Assert.NotNull(fileStream); Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream); var fileBytes = ReadFileContent(fileStream!);
Assert.Equal(input.Length, bufferingStream.Length); Assert.Equal(input.Length, bufferingStream.Length);

View File

@ -214,7 +214,7 @@ namespace Microsoft.AspNetCore.WebUtilities
var readOnlySequence = new ReadOnlySequence<byte>(encoding.GetBytes("foo=bar&baz=boo")); var readOnlySequence = new ReadOnlySequence<byte>(encoding.GetBytes("foo=bar&baz=boo"));
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -233,7 +233,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -252,7 +252,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.KeyLengthLimit = int.MaxValue; formReader.KeyLengthLimit = int.MaxValue;
formReader.ValueLengthLimit = int.MaxValue; formReader.ValueLengthLimit = int.MaxValue;
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false);
@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.KeyLengthLimit = int.MaxValue; formReader.KeyLengthLimit = int.MaxValue;
formReader.ValueLengthLimit = int.MaxValue; formReader.ValueLengthLimit = int.MaxValue;
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false);
@ -315,7 +315,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -333,7 +333,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -371,7 +371,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null, encoding); var formReader = new FormPipeReader(null!, encoding);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -388,7 +388,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
Assert.True(readOnlySequence.IsEmpty); Assert.True(readOnlySequence.IsEmpty);
@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.KeyLengthLimit = 2; formReader.KeyLengthLimit = 2;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -419,7 +419,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.KeyLengthLimit = 2; formReader.KeyLengthLimit = 2;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -433,7 +433,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.ValueLengthLimit = 2; formReader.ValueLengthLimit = 2;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -447,7 +447,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.ValueLengthLimit = 2; formReader.ValueLengthLimit = 2;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -461,7 +461,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.KeyLengthLimit = 10; formReader.KeyLengthLimit = 10;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -475,7 +475,7 @@ namespace Microsoft.AspNetCore.WebUtilities
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null); var formReader = new FormPipeReader(null!);
formReader.ValueLengthLimit = 10; formReader.ValueLengthLimit = 10;
var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true)); var exception = Assert.Throws<InvalidDataException>(() => formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true));
@ -506,7 +506,7 @@ namespace Microsoft.AspNetCore.WebUtilities
{ {
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null) var formReader = new FormPipeReader(null!)
{ {
KeyLengthLimit = 3 KeyLengthLimit = 3
}; };
@ -527,7 +527,7 @@ namespace Microsoft.AspNetCore.WebUtilities
{ {
KeyValueAccumulator accumulator = default; KeyValueAccumulator accumulator = default;
var formReader = new FormPipeReader(null) var formReader = new FormPipeReader(null!)
{ {
ValueLengthLimit = 3 ValueLengthLimit = 3
}; };

View File

@ -443,12 +443,12 @@ namespace Microsoft.AspNetCore.WebUtilities
return new MemoryStream(data.ToArray()); return new MemoryStream(data.ToArray());
} }
public static IEnumerable<object[]> HttpRequestNullData() public static IEnumerable<object?[]> HttpRequestNullData()
{ {
yield return new object[] { null, Encoding.UTF8, ArrayPool<byte>.Shared, ArrayPool<char>.Shared }; yield return new object?[] { null, Encoding.UTF8, ArrayPool<byte>.Shared, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), null, ArrayPool<byte>.Shared, ArrayPool<char>.Shared }; yield return new object?[] { new MemoryStream(), null, ArrayPool<byte>.Shared, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), Encoding.UTF8, null, ArrayPool<char>.Shared }; yield return new object?[] { new MemoryStream(), Encoding.UTF8, null, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), Encoding.UTF8, ArrayPool<byte>.Shared, null }; yield return new object?[] { new MemoryStream(), Encoding.UTF8, ArrayPool<byte>.Shared, null };
} }
public static IEnumerable<object[]> HttpRequestDisposeData() public static IEnumerable<object[]> HttpRequestDisposeData()
@ -487,10 +487,10 @@ namespace Microsoft.AspNetCore.WebUtilities
public static IEnumerable<object[]> ReadLineData() public static IEnumerable<object[]> ReadLineData()
{ {
yield return new object[] { new Func<HttpRequestStreamReader, Task<string>>((httpRequestStreamReader) => yield return new object[] { new Func<HttpRequestStreamReader, Task<string?>>((httpRequestStreamReader) =>
Task.FromResult(httpRequestStreamReader.ReadLine()) Task.FromResult(httpRequestStreamReader.ReadLine())
)}; )};
yield return new object[] { new Func<HttpRequestStreamReader, Task<string>>((httpRequestStreamReader) => yield return new object[] { new Func<HttpRequestStreamReader, Task<string?>>((httpRequestStreamReader) =>
httpRequestStreamReader.ReadLineAsync() httpRequestStreamReader.ReadLineAsync()
)}; )};
} }

View File

@ -679,12 +679,12 @@ namespace Microsoft.AspNetCore.WebUtilities
} }
} }
public static IEnumerable<object[]> HttpResponseStreamWriterData() public static IEnumerable<object?[]> HttpResponseStreamWriterData()
{ {
yield return new object[] { null, Encoding.UTF8, ArrayPool<byte>.Shared, ArrayPool<char>.Shared }; yield return new object?[] { null, Encoding.UTF8, ArrayPool<byte>.Shared, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), null, ArrayPool<byte>.Shared, ArrayPool<char>.Shared }; yield return new object?[] { new MemoryStream(), null, ArrayPool<byte>.Shared, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), Encoding.UTF8, null, ArrayPool<char>.Shared }; yield return new object?[] { new MemoryStream(), Encoding.UTF8, null, ArrayPool<char>.Shared };
yield return new object[] { new MemoryStream(), Encoding.UTF8, ArrayPool<byte>.Shared, null }; yield return new object?[] { new MemoryStream(), Encoding.UTF8, ArrayPool<byte>.Shared, null };
} }
public static IEnumerable<object[]> HttpResponseDisposeData() public static IEnumerable<object[]> HttpResponseDisposeData()

View File

@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable disable warnings
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.WebUtilities
[Fact] [Fact]
public void AddQueryStringWithNullValueThrows() public void AddQueryStringWithNullValueThrows()
{ {
Assert.Throws<ArgumentNullException>("value" ,() => QueryHelpers.AddQueryString("http://contoso.com/", "hello", null)); Assert.Throws<ArgumentNullException>("value" ,() => QueryHelpers.AddQueryString("http://contoso.com/", "hello", null!));
} }
[Theory] [Theory]
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.WebUtilities
"http://contoso.com/someaction?hello=world&some=text&another=#name#something")] "http://contoso.com/someaction?hello=world&some=text&another=#name#something")]
public void AddQueryStringWithDictionary(string uri, string expectedUri) public void AddQueryStringWithDictionary(string uri, string expectedUri)
{ {
var queryStrings = new Dictionary<string, string>() var queryStrings = new Dictionary<string, string?>()
{ {
{ "hello", "world" }, { "hello", "world" },
{ "some", "text" }, { "some", "text" },

View File

@ -37,7 +37,7 @@ namespace System.Buffers
if (_disposed) if (_disposed)
return; return;
_array = null; _array = null!;
_disposed = true; _disposed = true;
} }
} }

View File

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -112,8 +114,8 @@ namespace System.Buffers
int i = 0; int i = 0;
BufferSegment last = null; BufferSegment? last = null;
BufferSegment first = null; BufferSegment? first = null;
do do
{ {
@ -137,7 +139,7 @@ namespace System.Buffers
} }
else else
{ {
last = last.Append(memory); last = last!.Append(memory);
} }
i++; i++;
} while (i < inputs.Length); } while (i < inputs.Length);

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
#if NETCOREAPP #if NETCOREAPP
using System.Buffers; using System.Buffers;
@ -353,7 +355,7 @@ namespace Microsoft.Extensions.Internal
int bufferSize = GetArraySizeRequiredToEncode(input.Length); int bufferSize = GetArraySizeRequiredToEncode(input.Length);
char[] bufferToReturnToPool = null; char[]? bufferToReturnToPool = null;
Span<char> buffer = bufferSize <= 128 Span<char> buffer = bufferSize <= 128
? stackalloc char[bufferSize] ? stackalloc char[bufferSize]
: bufferToReturnToPool = ArrayPool<char>.Shared.Rent(bufferSize); : bufferToReturnToPool = ArrayPool<char>.Shared.Rent(bufferSize);