From 3d4a2982d10266b14f26a0649ad9ab91f5b6d253 Mon Sep 17 00:00:00 2001 From: Sarah Zakarias Date: Thu, 30 Nov 2023 11:10:19 +0100 Subject: [PATCH] Disregard ignored advisories in pub get/upgrade report (#4064) --- lib/src/pubspec.dart | 1 + lib/src/pubspec_parse.dart | 34 +++++++++++++++++++ lib/src/solver/report.dart | 5 ++- test/get/hosted/advisory_test.dart | 32 +++++++++++++++++ .../do not show ignored advisories.txt | 13 +++++++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 test/testdata/goldens/get/hosted/advisory_test/do not show ignored advisories.txt diff --git a/lib/src/pubspec.dart b/lib/src/pubspec.dart index f8bfe8ca5..f65c8ab20 100644 --- a/lib/src/pubspec.dart +++ b/lib/src/pubspec.dart @@ -383,6 +383,7 @@ class Pubspec extends PubspecBase { collectError(() => executables); collectError(() => falseSecrets); collectError(() => sdkConstraints); + collectError(() => ignoredAdvisories); return errors; } diff --git a/lib/src/pubspec_parse.dart b/lib/src/pubspec_parse.dart index 3ea5f88e0..4cff195b4 100644 --- a/lib/src/pubspec_parse.dart +++ b/lib/src/pubspec_parse.dart @@ -138,6 +138,40 @@ abstract class PubspecBase { bool _parsedPublishTo = false; String? _publishTo; + /// The list of advisory IDs to be ignored when reporting security advisories + /// affecting dependencies. + List get ignoredAdvisories { + var advisoryIDs = _ignoredAdvisories; + if (advisoryIDs != null) { + return advisoryIDs; + } + advisoryIDs = []; + + Never ignoredAdvisoriesError(SourceSpan span) => _error( + '"ignored_advisories" field must be a list of advisory IDs', + span, + ); + + final ignoredAdvisoriesNode = fields.nodes['ignored_advisories']; + if (ignoredAdvisoriesNode == null) { + return _ignoredAdvisories = List.unmodifiable(advisoryIDs); + } + if (ignoredAdvisoriesNode is! YamlList) { + ignoredAdvisoriesError(ignoredAdvisoriesNode.span); + } + for (final node in ignoredAdvisoriesNode.nodes) { + final value = node.value; + if (value is! String) { + ignoredAdvisoriesError(node.span); + } + advisoryIDs.add(value); + } + + return _ignoredAdvisories = List.unmodifiable(advisoryIDs); + } + + List? _ignoredAdvisories; + /// The list of patterns covering _false-positive secrets_ in the package. /// /// This is a list of git-ignore style patterns for files that should be diff --git a/lib/src/solver/report.dart b/lib/src/solver/report.dart index 8e95743ac..cae8a05ed 100644 --- a/lib/src/solver/report.dart +++ b/lib/src/solver/report.dart @@ -421,7 +421,10 @@ $contentHashesDocumentationUrl if (advisories != null && advisories.isNotEmpty) { final advisoryFootnotes = []; - for (final adv in advisories.take(maxAdvisoryFootnotesPerLine)) { + final reportedAdvisories = advisories + .where((adv) => !_rootPubspec.ignoredAdvisories.contains(adv.id)) + .take(maxAdvisoryFootnotesPerLine); + for (final adv in reportedAdvisories) { advisoryFootnotes.add(advisoriesIds.length); advisoriesIds.add(adv.id); } diff --git a/test/get/hosted/advisory_test.dart b/test/get/hosted/advisory_test.dart index 805b45c3e..b54efc73e 100644 --- a/test/get/hosted/advisory_test.dart +++ b/test/get/hosted/advisory_test.dart @@ -106,4 +106,36 @@ Future main() async { ); await ctx.run(['get']); }); + + testWithGolden('do not show ignored advisories', (ctx) async { + final server = await servePackages(); + server + ..serve('foo', '1.2.3') + ..serve('foo', '2.0.0') + ..serve('baz', '1.0.0'); + + await d.dir(appPath, [ + d.pubspec( + { + 'name': 'app', + 'dependencies': { + 'foo': '^1.0.0', + 'baz': '^1.0.0', + }, + 'ignored_advisories': ['123'], + }, + ), + ]).create(); + server.affectVersionsByAdvisory( + name: 'foo', + advisoryId: '123', + affectedVersions: ['1.2.3'], + ); + server.affectVersionsByAdvisory( + name: 'foo', + advisoryId: '456', + affectedVersions: ['1.2.3'], + ); + await ctx.run(['get']); + }); } diff --git a/test/testdata/goldens/get/hosted/advisory_test/do not show ignored advisories.txt b/test/testdata/goldens/get/hosted/advisory_test/do not show ignored advisories.txt new file mode 100644 index 000000000..32537b540 --- /dev/null +++ b/test/testdata/goldens/get/hosted/advisory_test/do not show ignored advisories.txt @@ -0,0 +1,13 @@ +# GENERATED BY: test/get/hosted/advisory_test.dart + +## Section 0 +$ pub get +Resolving dependencies... ++ baz 1.0.0 ++ foo 1.2.3 (affected by advisory: [^0], 2.0.0 available) +Changed 2 dependencies! +Dependencies are affected by security advisories: + [^0]: https://github.com/advisories/456 +1 package has newer versions incompatible with dependency constraints. +Try `dart pub outdated` for more information. +