-
Notifications
You must be signed in to change notification settings - Fork 654
Replace int.Parse() with int.TryParse() to avoid exceptions caused by overflowing values in tags #2703
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
Replace int.Parse() with int.TryParse() to avoid exceptions caused by overflowing values in tags #2703
Conversation
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.
Great stuff, I just have some design feedback: Please add the method SemanticVersion.TryParse()
instead to deal with this and then use Int32.TryParse()
within it to avoid the exceptions.
Sure, will update this evening and add tests. Thanks! Should we swallow the errors silently or would you like it to print to STDERR? |
👍🏼
If you're able to inject an instance of |
Updated to use Defaulted the out param to null, the code returns if major version is not matched (there was no default 0 value set for this previously) or if the I looked into the logging but could't see a decent way to provide a logger. I'm wondering how useful it is now to check each field if we can't provide details of the failure to the user? I noticed the public static SemanticVersion Parse(string version, string tagPrefixRegex)
{
if (!TryParse(version, tagPrefixRegex, out var semanticVersion))
throw new WarningException($"Failed to parse {version} into a Semantic Version");
return semanticVersion;
} |
da7882e
to
6e4d1b6
Compare
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.
Updated to use
TryParse()
👍🏼
the code is already within a method called
SemanticVersion.TryParse()
Sorry, I did not explore the surrounding code and context fully.
unless you meant to create a private method for this?
No, this is perfect.
Defaulted the out param to null, the code returns if major version is not matched (there was no default 0 value set for this previously) or if the
int.TryParse()s
fail.
Sounds reasonable to me.
I looked into the logging but could't see a decent way to provide a logger. I'm wondering how useful it is now to check each field if we can't provide details of the failure to the user?
If it's difficult it's not worth it. If possible, we can log on the outside (when SemanticVersion.TryParse
returns false
) instead.
I noticed the
SemanticVersion.Parse()
method wrapsSemanticVersion.TryParse()
and this throws aWarningException
. Perhaps it could bubble-up/throw an exception with information about the parsing failure?
I'm not sure why we would need the Parse
method. Our own codebase should be confidently and consistently using TryParse
everywhere, imho.
public static SemanticVersion Parse(string version, string tagPrefixRegex) { if (!TryParse(version, tagPrefixRegex, out var semanticVersion)) throw new WarningException($"Failed to parse {version} into a Semantic Version"); return semanticVersion; }
This works if we actually want exceptions, but if this again is just caught and written to ILog
, it would be better to just use TryParse
and log if it returns false
.
src/GitVersion.Core/VersionCalculation/SemanticVersioning/SemanticVersion.cs
Outdated
Show resolved
Hide resolved
@james-bjss any updates? |
Sorry, have been away on leave and busy with day job. Will try and take a look at this again this week. |
eaf1224
to
2159745
Compare
@asbjornu @arturcic - Have updated the PR with the requested changes. The Is this a flaky test or do I need to dig deeper? |
It's a flaky test unfortunately. |
} | ||
|
||
public static SemanticVersionPreReleaseTag Parse(string preReleaseTag) | ||
public static SemanticVersionPreReleaseTag TryParse(string preReleaseTag) |
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.
Since this method does not have the bool TryParse(string, out T)
signature, I'm not sure it should be named TryParse
. The method signature indicates Parse
while its behaviour indicates TryParse
. How much breakage would it cause to change the method signature to bool TryParse(string, out SemanticVersionPreReleaseTag)
?
public static SemanticVersionPreReleaseTag TryParse(string preReleaseTag) | |
public static bool TryParse(string preReleaseTag, out SemanticVersionPreReleaseTag) |
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.
The Int.TryParse()
line in the SemanticVersionPreReleaseTag
defaults the value to null if it's not parseable.
Will let you be the guide here as to whether you would prefer to rename the method it back to Parse OR return false on failure and modify the signature as you have suggested above OR take the same approach as in SemanticVersion.cs
In terms of breakage the only place it seems to be directly called is within SemanticVersion.cs
when it constructs and returns a new SemanticVersion
and assigns a pre-release tag.
The tests do not seem to directly reference this method directly either.
From there there we can decide if we want to do anything about it eg. returning false from SemanticVersion.TryParse()
which would result in the calling method Parse()
throwing a new Warning exception.
NB. All of the code calls SemanticVersion.Parse()
nothing seems to call the TryParse()
directly. I could follow the same pattern in SemanticVersionPreReleaseTag
and wrap the method?
Calling Code in TryParse()
semanticVersion = new SemanticVersion
{
Major = major,
Minor = minor,
Patch = patch,
PreReleaseTag = SemanticVersionPreReleaseTag.TryParse(parsed.Groups["Tag"].Value),
BuildMetaData = semanticVersionBuildMetaData
};`
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.
I would prefer consistent use of TryParse
returning bool
everywhere, if possible.
This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions. |
@james-bjss, could you please go over my feedback and rebase this onto the |
While I think I've solved this by changing |
Hi, Sorry for the late reply. I have had quite a lot on work-wise. Will try to grab some time to revisit this and put this PR to bed. Just to confirm the outstanding change is to replace all usages with I suppose that then means adding logic in all the calling code to check the repose and throw an error? |
I believe a |
This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions. |
@james-bjss, can you please complete this PR one way or another? 🙏🏼 |
9801764
to
b7a7608
Compare
This one is not needed anymore due to recent changes in the |
Replace int.Parse() with int.TryParse() This is to prevent the tool failing with an overflowing value.
Description
If a tag has a suffix which is a numeric value larger than a 32bit int then gitversion fails with an Overflow error.
Whilst the tag can be ignore by using the
tag-prefix
config It would be preferable if it didn't fall over when it encounters such a tag.Related Issue
#2390
Motivation and Context
We have some tags in our repository which are suffixed with a timestamp value (created by another build process).
We have used the
tag-prefix
config to ignore these, but without it gitversion falls over with an Int32 Overflow exception.How Has This Been Tested?
Screenshots (if appropriate):
Checklist: