-
Notifications
You must be signed in to change notification settings - Fork 645
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
Block packages with illegal package dependency version ranges #3728
Conversation
@@ -1149,7 +1150,8 @@ private ActionResult EditFailed(string id, EditPackageRequest formData, Package | |||
package = await _packageService.CreatePackageAsync(nugetPackage, packageStreamMetadata, currentUser, commitChanges: false); | |||
Debug.Assert(package.PackageRegistration != null); | |||
} | |||
catch (EntityException ex) | |||
catch(Exception ex) | |||
when (ex is PackagingException || ex is EntityException) |
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.
nit new line looks weird here
private string[] GetErrors(Stream nuspecStream) | ||
[Theory] | ||
[InlineData("$version$")] | ||
[InlineData("[15.106.0.preview]")] |
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.
is
<dependency id=""a.b.c"" version="" />
is legal?
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 NuspecReader.GetDependencyGroups(useStrictVersionCheck: true)
does not throw apparently when the dependency version is ""
. Should it? It currently still does a silent fallback to VersionRange.All
- aka (,)
.
If it should throw, that means another fix is due on the NuGet.Packaging
client lib.
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.
Imho, when using useStrictVersionCheck: true
, we should treat null
and ""
as invalid versions, and thus throw.
However, the PR that added the overload for strict version checks explicitly added null
and ""
in the test data for valid version ranges (highlight). An oversight? Or conscious?
Seems like a question @emgarten and @joelverhagen may want to comment on. The fix in the client lib is pretty trivial, but as you can tell, rather important :)
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.
Our docs specifically state that you can leave the version range unspecified, and what will happen. IMO we should keep this behavior the same, or, at the bare minimum, investigate how many packages have this issue before changing it.
https://docs.microsoft.com/en-us/nuget/create-packages/dependency-versions#version-ranges
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 spoke to @emgarten and @joelverhagen before implementing this change, and the conclusion was that, moving forward, we should be strict and block this from happening. The documented behavior was more a hack to support floating versions if I understood correctly. The change to reject empty dependency version ranges is also in line with the recommendation as per the docs.
For consistent behavior, it's recommended to always specify a version or version range for package dependencies.
If no version is specified for a dependency, NuGet behaves as follows:
- NuGet v2.7.2 and earlier: The latest package version will be used
- NuGet v2.8 and later: The lowest package version will be used
I think we should add:
- NuGet v2.8 to v4.1.0: The lowest package version will be used
- NuGet v4.3.0 and above: no longer supported and considered an invalid dependency version range
/// <exception cref="PackagingException"> | ||
/// This exception will be thrown if an invalid package dependency version range is detected. | ||
/// </exception> | ||
/// <exception cref="EntityException"> |
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.
This "contract" is a bit strange... we throw EntityException for every bad metadata value, but a different exception (PackagingException) for bad dependencies.
I suggest wrapping it here in InvalidPackageException. This way we will have a clear contract with the callers.
Also, noticed there are place where we call EnsureValid, but don't expose the failure message correctly:
https://github.com/NuGet/NuGetGallery/blob/master/src/NuGetGallery/Controllers/PackagesController.cs#L234
This is one example why having a single exception type thrown will be better.
@@ -249,7 +249,7 @@ public class ManifestValidatorFacts | |||
</metadata> | |||
</package>"; | |||
|
|||
private const string NuSpecDependencySetContainsInvalidTargetFramework = @"<?xml version=""1.0""?> | |||
private const string NuSpecDependencySetContainsInvalidVersionRange = @"<?xml version=""1.0""?> |
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.
With this change, are we no longer testing invalid target frameworks?
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.
That string was not used anywhere, I merely put it to use in a different scenario :)
private string[] GetErrors(Stream nuspecStream) | ||
[Theory] | ||
[InlineData("$version$")] | ||
[InlineData("[15.106.0.preview]")] |
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.
Our docs specifically state that you can leave the version range unspecified, and what will happen. IMO we should keep this behavior the same, or, at the bare minimum, investigate how many packages have this issue before changing it.
https://docs.microsoft.com/en-us/nuget/create-packages/dependency-versions#version-ranges
public static PackageMetadata FromNuspecReader(NuspecReader nuspecReader) | ||
{ | ||
return new PackageMetadata( | ||
nuspecReader.GetMetadata().ToDictionary(kvp => kvp.Key, kvp => kvp.Value), | ||
nuspecReader.GetDependencyGroups(), | ||
nuspecReader.GetDependencyGroups(useStrictVersionCheck: true), |
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.
Not in the scope of this PR, but do we potentially have similar issues with our framework reference groups, packages types, or min client version?
…pendency version ranges + adjust tests for useStrictVersionCheck changes
7d8d2b7
to
e3ba44f
Compare
Updated this PR to consume the fresh builds that include the Final pair of eyes please? :) @joelverhagen @scottbommarito @skofman1 |
Fixes #3482
Using
strictVersionCheck=true
by default, to block packages from being uploaded to nuget.org if they contain package dependencies with an invalid version range.