Tests for safety of string format calls#4194
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
My first code fix for CKAN was to remove a superfluous
String.Formatcall that was causing exceptions to be thrown because externally-generated strings were being used as part of a format string (see #2111).This problem generalizes; any call to
IUser.RaiseMessageorIUser.RaiseErrorcan throw an exception if the first parameter isn't a valid format string. We can ensure that a string literal is safe by looking at it, and we can ensure that an i18n resource is safe by inspecting our resx files, but anytime a value is externally sourced, it isn't safe to use it as a format string because curly braces could turn up any time and ruin our day.In principle, the C# compiler could check this and emit warnings similar to what it does for nullable references, but currently it doesn't. The closest thing is the
StringSyntaxattribute, which can be used to mark a parameter as a format string, but which doesn't have any built-in functionality associated with it.Changes
MonoCecilAnalysisTestsBasebase class is factored out of the test from Add test to check GUI thread safety #3914StringFormatSafetyTestsclass inherits fromMonoCecilAnalysisTestsBaseand scans all code in all of our assemblies for calls to functions with theStringSyntaxattribute. These calls are deemed safe if the argument list is non-empty, if the format string is a string literal, or if the format string is fromProperties.Resources; otherwise a test failure is logged.StringSyntaxattribute"{0}", or to remove a superfluous call tostring.Format, or other such solutionsThis guard rail will help us to write safer code.