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

Restrict nuget version range allows incorrect ranges #3917

Merged

Conversation

erdembayar
Copy link
Contributor

@erdembayar erdembayar commented Feb 23, 2021

Fixes: NuGet/Home#9145

Regression? Last working version:

Description

See: https://nugettoolsdev.azurewebsites.net/5.5.0-preview.2.6382/parse-version-range?versionRange=%5B10.0.0%2C+9.0.0%29

[10.0.0, 9.0.0)

This range is empty and there's no reasonable scenario where it's necessary.

This has always been the case, all the way to 2.5 https://nugettoolsdev.azurewebsites.net/2.5.0/parse-version-range?versionRange=%5B10.0.0%2C+9.0.0%29.

Now we'll throw exception in above case. Also we consider [9.0.0, 9.0.0), (9.0.0, 9.0.0] as illogical now.
But we're not touch (9.0.0, 9.0.0) even though it's technically illogical range, it's used as empty range in many unit test cases, let's not overdo it.

PR Checklist

  • PR has a meaningful title

  • PR has a linked issue.

  • Described changes

  • Tests

    • Automated tests added
    • OR
    • Test exception
    • OR
    • N/A
  • Documentation

    • Documentation PR or issue filled
    • OR
    • N/A

@erdembayar
Copy link
Contributor Author

@nkolev92
How about "[1.0.0, 1.0.0)"? Some tests are failing.
Personally, I want to treat as bad range.

@nkolev92
Copy link
Member

That seems like a bad range, but I'm not sure what you are to tell me by "some tests are failing".

@erdembayar
Copy link
Contributor Author

That seems like a bad range, but I'm not sure what you are to tell me by "some tests are failing".

For example below test is now failing, because input is actually [2.3.1-RC+srv01-a5c5ff9, 2.3.1-RC+srv02-dbf5ec0) means [2.3.1-RC, 2.3.1-RC) ~ [a,a) is here. I believe [a,a) is illogical range. Something can't be exluding and including same thing a same time.

[InlineData("[2.3.1-RC+srv01-a5c5ff9, 2.3.1-RC+srv02-dbf5ec0)", "2.3.1-RC+srv00-a5c5ff9")]
public void NuGetVersionRangeWithGitCommit(string verSpec, string ver)
{
// Arrange
var versionInfo = VersionRange.Parse(verSpec);

@nkolev92
Copy link
Member

I think that the test could be better.

@erdembayar erdembayar force-pushed the dev-eryondon-9145NuGetVersionRangeAllowsIncorrectRanges branch from 8bd1959 to da47744 Compare February 24, 2021 19:54
@erdembayar erdembayar marked this pull request as ready for review February 24, 2021 23:58
@erdembayar erdembayar requested a review from a team as a code owner February 24, 2021 23:58
@erdembayar
Copy link
Contributor Author

I think that the test could be better.

Removed only that case, it's illogical test input.

@erdembayar erdembayar changed the title Be restict on nuget version range allows incorrect ranges Restrict nuget version range allows incorrect ranges Feb 25, 2021
@erdembayar
Copy link
Contributor Author

@nkolev92
[2.0.0) it it illogical range? I guess it's. I believe it should be [2.0.0, ) or [2.0.0, *) valid, yeah?

@nkolev92
Copy link
Member

[2.0.0) likely normalizes to [2.0.0,2.0.0) which is equivalent to the one you mentioned above.
[2.0.0, ) is different and it's the normalized version of 2.0.0.

[2.0.0, *) is not a valid range, because the floating part cannot be part of the upper range. Only a min range can be floating.

@erdembayar
Copy link
Contributor Author

@NuGet/nuget-client
Hi.
Ready for review, please review.

Copy link
Member

@nkolev92 nkolev92 left a comment

Choose a reason for hiding this comment

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

The general idea seems good.
Maybe we can try simplifying the code a bit?

Why does your checklist have tests exception selected?

[InlineData("[2.0.0)")]
[InlineData("(2.0.0]")]
[InlineData("[2.0.0, *)")]
public void VersionRange_LogicallyIncorrectRanges_Throws(string range)
Copy link
Member

Choose a reason for hiding this comment

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

The correct name according to the guide would be Parse_****_****

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok . Renamed.

src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs Outdated Show resolved Hide resolved
@erdembayar
Copy link
Contributor Author

The general idea seems good.
Maybe we can try simplifying the code a bit?

Why does your checklist have tests exception selected?

Thank you for your review. I addressed your comments and made it more easy to reason. Please review again.

Copy link
Member

@nkolev92 nkolev92 left a comment

Choose a reason for hiding this comment

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

I think we can go even simpler than what we have right now :)

&& minVersion >= maxVersion
&& !(minVersion == maxVersion && isMinInclusive && isMaxInclusive)) // Exclude (9.0.0,9.0.0) since it's used as empty version range.
{
if (partsLength == 1)
Copy link
Member

Choose a reason for hiding this comment

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

This check can still be a lot simpler.

All comments aside, I'd expect return false covers all scenarios here and you don't need any of the parts checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. I addressed this one. Please check.

src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs Outdated Show resolved Hide resolved
src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs Outdated Show resolved Hide resolved
Comment on lines 239 to 263
// Illogical version range detection
if (minVersion != null && maxVersion != null
&& minVersion >= maxVersion
&& !(minVersion == maxVersion && isMinInclusive && isMaxInclusive)) // Exclude (9.0.0,9.0.0) since it's used as empty version range.
{
if (partsLength == 1)
{
var onePartValidation = isMinInclusive ^ isMaxInclusive; // (1.0.0] and [1.0.0) are invalid
onePartValidation |= !isMinInclusive && !isMaxInclusive; ; // or (1.0.0) is invalid
if (onePartValidation)
{
return false;
}
}
else
{
var manyPartsValidation = minVersion > maxVersion // If a > b then (a, b) range is invalid. But below 2 cases tests are a = b (equals).
| isMinInclusive // [1.0.0, 1.0.0) is invalid
| isMaxInclusive; // (1.0.0, 1.0.0] and [1.0.0, 1.0.0] are invalid
if (manyPartsValidation)
{
return false;
}
}
}

Copy link
Contributor

@kartheekp-ms kartheekp-ms Mar 5, 2021

Choose a reason for hiding this comment

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

I think we can change the above logic as follows. Hope it covers all edge cases :)

                //(1.0.0) , (1.0.0] and [1.0.0) invalid [1.0.0] is the only valid version number
                if (parts.Length == 1
                    && !(isMinInclusive && isMaxInclusive))
                {
                    return false;
                }
            if (minVersion != null && maxVersion != null)
            {
                int result = minVersion.CompareTo(maxVersion);

                //minVersion is equal to maxVersion (1.0.0, 1.0.0], [1.0.0, 1.0.0)
                if (result == 0
                    && (isMinInclusive ^ isMaxInclusive))
                    return false;

                //minVersion > maxVersion
                if (result > 0)
                    return false;
            }

Copy link
Contributor Author

@erdembayar erdembayar Mar 23, 2021

Choose a reason for hiding this comment

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

Ok. Taken your suggestion. Please review again now.

@erdembayar erdembayar force-pushed the dev-eryondon-9145NuGetVersionRangeAllowsIncorrectRanges branch from 59f5cc4 to 5e6a2ba Compare March 23, 2021 04:18
@erdembayar erdembayar force-pushed the dev-eryondon-9145NuGetVersionRangeAllowsIncorrectRanges branch from 5e6a2ba to b34ad7b Compare March 23, 2021 16:52
@erdembayar
Copy link
Contributor Author

Addressed PR review comments. Ready for review.

Copy link
Member

@nkolev92 nkolev92 left a comment

Choose a reason for hiding this comment

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

1 clean-up nit.

Nicely done! 👏

@@ -123,6 +123,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v
NuGetVersion minVersion = null;
NuGetVersion maxVersion = null;
FloatRange floatRange = null;
int partsLength = 0;
Copy link
Member

@nkolev92 nkolev92 Mar 26, 2021

Choose a reason for hiding this comment

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

you probably don't need this here anymore. Everything is in the internal { }

@erdembayar
Copy link
Contributor Author

@kartheekp-ms
Can review again please?

@erdembayar erdembayar merged commit 44210f1 into dev Mar 27, 2021
@erdembayar erdembayar deleted the dev-eryondon-9145NuGetVersionRangeAllowsIncorrectRanges branch March 27, 2021 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NuGetVersionRange allows logically incorrect ranges to be parsed
3 participants