Skip to content

Refactor DesignerSerializationManager dictionary usage to use TryGetValue #8702

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

Conversation

elachlan
Copy link
Contributor

@elachlan elachlan commented Feb 26, 2023

Refactor dictionary usage to use TryGetValue.

Addresses feedback from:
#8353 (comment)

Microsoft Reviewers: Open in CodeFlow

@elachlan elachlan requested a review from a team as a code owner February 26, 2023 22:12
@ghost ghost assigned elachlan Feb 26, 2023
@elachlan
Copy link
Contributor Author

@KalleOlaviNiemitalo
Copy link

Would this deserve a test too?

@elachlan
Copy link
Contributor Author

Would this deserve a test too?

I'll look into it when I have more time. I am not sure how to go about it.

serializer = serializers[objectType];
if (serializer is not null && !serializerType.IsAssignableFrom(serializer.GetType()))
// I don't double hash here. It will be a very rare day where multiple types of serializers will be used in the same scheme. We still handle it, but we just don't cache.
if (serializers.TryGetValue(objectType, out serializer) && !serializerType.IsAssignableFrom(serializer.GetType()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for objectType to map to a null value in serializers? If so, we should check if serializer is null before calling serializer.GetType()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We check objectType for null just above on line 416.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @lonitra meant, if serializers contained an entry in which the key (i.e. objectType) is not null but the value (i.e. serializer) is null, that could cause a NullReferenceException in serializer.GetType(). Although the code checks objectType is not null, that doesn't help against this risk.

Anyway, it won't happen, because the only code that adds anything to serializers is here and it does not add null values:

if (serializer is not null && session is not null)
{
serializers ??= new();
serializers[objectType] = serializer;
}

ArgumentNullException.ThrowIfNull(value);

CheckSession();
// Check our local nametable first
if (namesByInstance is not null)
if (namesByInstance is not null && namesByInstance.TryGetValue(value, out string? name))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here. If value can map to a null value in namesByInstance, we should check if name is not null before returning it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namesByInstance/instancesByName do not accept a nullable value.

@lonitra
Copy link
Member

lonitra commented Feb 27, 2023

Would this deserve a test too?

I'll look into it when I have more time. I am not sure how to go about it.

Off the top of my head I am not sure how complicated our unit tests for DesignerSerializerManager are, but it is worth revisiting those tests to see if our existing tests that exercise these methods calling to the now dictionaries also exercises it with keys that don't exist to ensure we are not unexpectedly throwing.

@lonitra lonitra added the waiting-author-feedback The team requires more information from the author label Feb 27, 2023
@dreddy-work
Copy link
Member

@elachlan, just checking if this is still on your radar.

@elachlan
Copy link
Contributor Author

elachlan commented Mar 9, 2023

Yes. Work has taken over a bit due to some deadlines. I'll see what I can do.

@ghost ghost removed the waiting-author-feedback The team requires more information from the author label Mar 9, 2023
@dreddy-work dreddy-work added the waiting-author-feedback The team requires more information from the author label Mar 16, 2023
…used. serializers is only used in a session and only exists after the first call.
@ghost ghost removed the waiting-author-feedback The team requires more information from the author label Mar 28, 2023
@elachlan elachlan requested a review from lonitra March 28, 2023 22:29
@elachlan
Copy link
Contributor Author

elachlan commented Mar 28, 2023

I have tested locally and it fails without the fix. I've only added a test change for the serializers dictionary.

Sorry this took so long. I imagined it would take me a lot longer and had been busy with work.

@dreddy-work
Copy link
Member

@elachlan, did you get chance to respond on couple of open comment above?

@elachlan
Copy link
Contributor Author

I'll look today.

@elachlan
Copy link
Contributor Author

@dreddy-work I believe its addressed. But feel free to add to it if I have missed something.

@dreddy-work dreddy-work merged commit 14e7ca3 into dotnet:main Mar 31, 2023
@ghost ghost added this to the 8.0 Preview4 milestone Mar 31, 2023
@elachlan elachlan deleted the DesignerSerializationManager-FixDictionaryAccess branch March 31, 2023 20:52
@ghost ghost locked as resolved and limited conversation to collaborators May 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants