Skip to content
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

Missing argument validation on 'LoggerFactory.AddProvider' #45599

Closed
julealgon opened this issue Dec 4, 2020 · 6 comments · Fixed by #46002
Closed

Missing argument validation on 'LoggerFactory.AddProvider' #45599

julealgon opened this issue Dec 4, 2020 · 6 comments · Fixed by #46002
Labels
area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@julealgon
Copy link

Description

Microsoft.Extensions.Logging.LoggerFactory implements ILoggerFactory with a AddProvider(ILoggerProvider) method. However, it does not perform any argument validation on provider, meaning it will consider null as a "valid" provider and add it to the collection of providers internally.

Some operations inside the class will unnecessarily throw NullReferenceExceptions due to this behavior, like the Dispose method, which will capture these exceptions and do nothing.

One would expect that null providers are not accepted and the method should throw a ArgumentNullException.

Configuration

Net 5.0
Microsoft.Extensions.Logging latest (v5.0.0)

Other information

Here is where it loads up the provider:

public void AddProvider(ILoggerProvider provider)
{
if (CheckDisposed())
{
throw new ObjectDisposedException(nameof(LoggerFactory));
}
lock (_sync)
{
AddProviderRegistration(provider, dispose: true);

private void AddProviderRegistration(ILoggerProvider provider, bool dispose)
{
_providerRegistrations.Add(new ProviderRegistration
{
Provider = provider,
ShouldDispose = dispose
});

And here an example where exceptions will be generated and caught:

try
{
if (registration.ShouldDispose)
{
registration.Provider.Dispose();
}
}
catch
{
// Swallow exceptions on dispose
}

I'm not sure if this could cause further problems downstream when using the loggers from the factory.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-Extensions-Logging untriaged New issue has not been triaged by the area owner labels Dec 4, 2020
@ghost
Copy link

ghost commented Dec 4, 2020

Tagging subscribers to this area: @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Microsoft.Extensions.Logging.LoggerFactory implements ILoggerFactory with a AddProvider(ILoggerProvider) method. However, it does not perform any argument validation on provider, meaning it will consider null as a "valid" provider and add it to the collection of providers internally.

Some operations inside the class will unnecessarily throw NullReferenceExceptions due to this behavior, like the Dispose method, which will capture these exceptions and do nothing.

One would expect that null providers are not accepted and the method should throw a ArgumentNullException.

Configuration

Net 5.0
Microsoft.Extensions.Logging latest (v5.0.0)

Other information

Here is where it loads up the provider:

public void AddProvider(ILoggerProvider provider)
{
if (CheckDisposed())
{
throw new ObjectDisposedException(nameof(LoggerFactory));
}
lock (_sync)
{
AddProviderRegistration(provider, dispose: true);

private void AddProviderRegistration(ILoggerProvider provider, bool dispose)
{
_providerRegistrations.Add(new ProviderRegistration
{
Provider = provider,
ShouldDispose = dispose
});

And here an example where exceptions will be generated and caught:

try
{
if (registration.ShouldDispose)
{
registration.Provider.Dispose();
}
}
catch
{
// Swallow exceptions on dispose
}

I'm not sure if this could cause further problems downstream when using the loggers from the factory.

Author: julealgon
Assignees: -
Labels:

area-Extensions-Logging, untriaged

Milestone: -

@maryamariyan
Copy link
Member

maryamariyan commented Dec 4, 2020

As part of the effort to enable nullable annotations for extensions libraries (tracked here), we just recently annotated Logging.Abstractions, and that means ILoggerFactory implemented under Logging.Abstractions would actually expect to take a non-nullable ILoggerProvider for ILoggerFactory.AddProvider(ILoggerProvider).

When we enable nullable annotations for Microsoft.Extensions.Logging, it should take this into account for the code snippets you share above as well.

So I think, throwing ArgumentNullException would be mainly beneficial for when nullable annotations are not enabled.

@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Dec 4, 2020
@maryamariyan maryamariyan added this to the Future milestone Dec 4, 2020
@maryamariyan maryamariyan added the help wanted [up-for-grabs] Good issue for external contributors label Dec 4, 2020
@julealgon
Copy link
Author

So I think, throwing ArgumentNullException would be beneficial for when nullable annotations are not enabled.

I think this is ill-advised @maryamariyan : ArgumentNullExceptions should be thrown even in the case that correct nullable annotations are in place.

This is because as of right now, there is no runtime validation leveraging nullable annotations, so if consumers pass a null value, one would still see the same issues. Also keep in mind that people having nullable reference types disabled and also freely pass null into these methods without any warnings without using the ! operator.

I do hope to see C# and the runtime move into full-on runtime validation of these nullable constraints at some point, and then we could remove the manual argument validation from everywhere.

@Michael3161010
Copy link

I am looking for a good first issue to pick up, does anyone have an issue if I do that ?

ovebastiansen added a commit to ovebastiansen/runtime that referenced this issue Dec 12, 2020
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Dec 12, 2020
@maryamariyan
Copy link
Member

I am looking for a good first issue to pick up, does anyone have an issue if I do that ?

Seems like there is a PR for this now. @Michael3161010 you could perhaps pick another one from here and comment on the one you picked stating you picked it and would be creating a PR for it.

@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Dec 15, 2020
@maryamariyan
Copy link
Member

maryamariyan commented Dec 15, 2020

ArgumentNullExceptions should be thrown even in the case that correct nullable annotations are in place.

Thanks for the pointer @julealgon. We should throw even if nullable annotations are enabled, since the consuming library may not have nullable enabled. Also, e.g. Foo(null!) could get past compiler, and then in runtime with this fix we'd receive an ArgumentNullException which is better than the previous NRE.

cc: @safern

@ghost ghost locked as resolved and limited conversation to collaborators Jan 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants