From f1ff2c2f8b95dde92264e9d3240d8b6f1ee1d164 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 11 Feb 2022 14:28:42 +0100 Subject: [PATCH] null-safety, update dependencies, linter, formatter --- lib/src/api/typedefs.dart | 2 +- lib/src/api/uris.dart | 6 ++--- lib/src/api/whitelist.dart | 12 +++++----- lib/src/impl/attribute.dart | 4 ++-- lib/src/impl/cleanerimpl.dart | 6 ++--- lib/src/impl/collector.dart | 4 ++-- lib/src/impl/tag.dart | 4 ++-- lib/src/impl/whitelistimpl.dart | 16 ++++++------- pubspec.yaml | 11 ++++----- test/collector_test.dart | 41 ++++----------------------------- test/whitelist_test.dart | 16 ++++++------- 11 files changed, 43 insertions(+), 79 deletions(-) diff --git a/lib/src/api/typedefs.dart b/lib/src/api/typedefs.dart index 1d93a80..cdf434c 100644 --- a/lib/src/api/typedefs.dart +++ b/lib/src/api/typedefs.dart @@ -7,7 +7,7 @@ import 'package:htmlwhitelist/htmlwhitelist.dart'; /// Returns `true` if the given [tag] and [attributes] are accepted. /// /// [attributes] contains all attribute names and values of the source tag. -typedef bool Filter(String tag, Map attributes); +typedef bool Filter(String tag, Map attributes); /// Returns `true` if the given [name] matches. typedef bool Matcher(String name); diff --git a/lib/src/api/uris.dart b/lib/src/api/uris.dart index 34518f7..c800649 100644 --- a/lib/src/api/uris.dart +++ b/lib/src/api/uris.dart @@ -6,13 +6,13 @@ import 'package:htmlwhitelist/htmlwhitelist.dart'; /// Contains some utility functions to inspect uris. class Uris { + Uris._(); + static final String _test1 = 'http://x.y/'; static final String _test2 = 'ftp://y.x/'; static final Uri _testUri1 = Uri.parse(_test1); static final Uri _testUri2 = Uri.parse(_test2); - Uris._(); - /// Returns `true` if [uri] contains a relative path. /// /// A path is relative when, if it gets resolved by a different path, @@ -77,7 +77,7 @@ class Uris { /// - when the uri is resolved from any of the [allowed] uris, its path starts /// with that allowed uri. - static Filter external(String attribute, {Iterable allowed}) { + static Filter external(String attribute, {Iterable? allowed}) { var allowedUris = allowed == null ? const [] : new List.from(allowed); return (t, o) { diff --git a/lib/src/api/whitelist.dart b/lib/src/api/whitelist.dart index 89dcc38..341ab4d 100644 --- a/lib/src/api/whitelist.dart +++ b/lib/src/api/whitelist.dart @@ -9,6 +9,8 @@ import '../impl/whitelistimpl.dart'; /// Defines the rules for what tags, attribute names and attribute values /// are allowed in a piece of HTML. abstract class Whitelist { + Whitelist._(); + /// No tags allowed, only text nodes. static final Whitelist none = WhitelistImpl.none; @@ -88,8 +90,6 @@ abstract class Whitelist { when: Uris.hasAllowedScheme('src', ['http', 'https', 'data'])) .attributes('img', ['align', 'alt', 'height', 'title', 'width']); - Whitelist._(); - /// Creates a new Whitelist with additional allowed [tags]. /// /// The [tags] can be one of the following types: @@ -100,7 +100,7 @@ abstract class Whitelist { /// /// If [when] is provided, the tag will only be allowed if [when] /// applies. Only if [tags] matches will [when] be invoked. - Whitelist tags(dynamic tags, {Filter when}); + Whitelist tags(dynamic tags, {Filter? when}); /// Creates a new Whitelist with additional allowed [attributes] for the /// given [tags] that will be copied from the source. @@ -114,7 +114,7 @@ abstract class Whitelist { /// If [when] is provided, the attribute will only be copied if [when] /// applies. Only if both [tags] and [attributes] match will /// [when] be invoked. - Whitelist attributes(dynamic tags, dynamic attributes, {Filter when}); + Whitelist attributes(dynamic tags, dynamic attributes, {Filter? when}); /// Creates a new Whitelist with generated attributes for the /// given [tags]. @@ -130,8 +130,8 @@ abstract class Whitelist { /// /// If [when] is provided, the generator will only be invoked if [when] /// applies. Only if [tags] matches will [when] be invoked. - Whitelist extraAttributes(dynamic tags, AttributeGenerator generator, - {Filter when}); + Whitelist extraAttributes(dynamic tags, AttributeGenerator? generator, + {Filter? when}); /// Returns a safe copy of the [contents] after /// applying the rules of this Whitelist. diff --git a/lib/src/impl/attribute.dart b/lib/src/impl/attribute.dart index 6c891eb..1b97a34 100644 --- a/lib/src/impl/attribute.dart +++ b/lib/src/impl/attribute.dart @@ -5,12 +5,12 @@ import 'package:htmlwhitelist/htmlwhitelist.dart'; class Attribute { + Attribute(this._tags, this._generator, this._when); + final Matcher _tags; final AttributeGenerator _generator; final Filter _when; - Attribute(this._tags, this._generator, this._when); - void generate(String tag, Map attributes, AttributeCollector collector) { if (_tags(tag) && _when(tag, attributes)) { diff --git a/lib/src/impl/cleanerimpl.dart b/lib/src/impl/cleanerimpl.dart index 6e11ca4..9f62535 100644 --- a/lib/src/impl/cleanerimpl.dart +++ b/lib/src/impl/cleanerimpl.dart @@ -12,11 +12,11 @@ import 'collector.dart'; import 'tag.dart'; class CleanerImpl implements Cleaner { + CleanerImpl(this._tags, this._attributes); + final List _tags; final List _attributes; - CleanerImpl(this._tags, this._attributes); - @override DocumentFragment safeCopy(Node node) { var document = new Document(); @@ -31,7 +31,7 @@ class CleanerImpl implements Cleaner { var newTarget = target; var originalAttributes = new Map.unmodifiable(_toStringMap(node.attributes)); - var tag = node.localName; + var tag = node.localName!; if (_tagAllowed(tag, originalAttributes)) { newTarget = _copy(document, tag, originalAttributes); target.append(newTarget); diff --git a/lib/src/impl/collector.dart b/lib/src/impl/collector.dart index 69549d4..48eaac2 100644 --- a/lib/src/impl/collector.dart +++ b/lib/src/impl/collector.dart @@ -21,7 +21,7 @@ class Collector implements AttributeCollector { } @override - void append(String name, String value, {String separator}) { + void append(String name, String value, {String? separator}) { _checkNameAndValue(name, value); var previous = _values[name]; if (previous == null) { @@ -32,7 +32,7 @@ class Collector implements AttributeCollector { } @override - void prepend(String name, String value, {String separator}) { + void prepend(String name, String value, {String? separator}) { _checkNameAndValue(name, value); var previous = _values[name]; if (previous == null) { diff --git a/lib/src/impl/tag.dart b/lib/src/impl/tag.dart index 7770653..9e21d88 100644 --- a/lib/src/impl/tag.dart +++ b/lib/src/impl/tag.dart @@ -5,11 +5,11 @@ import 'package:htmlwhitelist/htmlwhitelist.dart'; class Tag { + Tag(this._matcher, this._when); + final Matcher _matcher; final Filter _when; - Tag(this._matcher, this._when); - bool allowed(String tag, Map attributes) => _matcher(tag) && _when(tag, attributes); } diff --git a/lib/src/impl/whitelistimpl.dart b/lib/src/impl/whitelistimpl.dart index 3ba6588..b79c8b3 100644 --- a/lib/src/impl/whitelistimpl.dart +++ b/lib/src/impl/whitelistimpl.dart @@ -10,29 +10,29 @@ import 'cleanerimpl.dart'; import 'tag.dart'; class WhitelistImpl implements Whitelist { + WhitelistImpl._(this._tags, this._attributes); + static final AttributeGenerator _noOp = (t, a, g) {}; static final Whitelist none = new WhitelistImpl._(const [], const []); final List _tags; final List _attributes; - Cleaner _cleaner; - - WhitelistImpl._(this._tags, this._attributes); + Cleaner? _cleaner; @override - Whitelist tags(dynamic tags, {Filter when}) => new WhitelistImpl._( + Whitelist tags(dynamic tags, {Filter? when}) => new WhitelistImpl._( (new List.from(_tags)..add(new Tag(_toMatcher(tags), when ?? always))), _attributes); @override - Whitelist attributes(dynamic tags, dynamic attributes, {Filter when}) => + Whitelist attributes(dynamic tags, dynamic attributes, {Filter? when}) => extraAttributes( tags, _attributeCopier(_toMatcher(attributes), when ?? always)); @override - Whitelist extraAttributes(dynamic tags, AttributeGenerator generator, - {Filter when}) => + Whitelist extraAttributes(dynamic tags, AttributeGenerator? generator, + {Filter? when}) => new WhitelistImpl._( _tags, (new List.from(_attributes) @@ -49,7 +49,7 @@ class WhitelistImpl implements Whitelist { if (_cleaner == null) { _cleaner = new CleanerImpl(_tags, _attributes); } - return _cleaner; + return _cleaner!; } Matcher _toMatcher(dynamic matcher) { diff --git a/pubspec.yaml b/pubspec.yaml index 5867d4d..b073273 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,17 +7,14 @@ description: > The main purpose is to convert html from an untrusted source to a version that's safe for rendering. -authors: -- Roel Spilker - homepage: https://github.com/topdesk/dart-html-whitelist -documentation: environment: - sdk: '>=1.21.0 <3.0.0' + sdk: '>=2.14.0 <3.0.0' dependencies: - html: '^0.13.2+2' + html: ^0.15.0 dev_dependencies: - test: '^1.3.0' + test: any + lints: 1.0.1 diff --git a/test/collector_test.dart b/test/collector_test.dart index 274cae5..1a046d1 100644 --- a/test/collector_test.dart +++ b/test/collector_test.dart @@ -33,14 +33,6 @@ void main() { ..['foo'] = 'foo'), ''); }); - - test('`null` name throws ArgumentError', () { - expect(() => a()[null] = 'bar', throwsArgumentError); - }); - - test('`null` value throws ArgumentError', () { - expect(() => a()['foo'] = null, throwsArgumentError); - }); }); group('ifAbsent(String name, String value)', () { @@ -57,17 +49,12 @@ void main() { }); test('works only once per attribute', () { - expect(string(a()..ifAbsent('foo', 'bar')..ifAbsent('foo', 'foo')), + expect( + string(a() + ..ifAbsent('foo', 'bar') + ..ifAbsent('foo', 'foo')), ''); }); - - test('`null` name throws ArgumentError', () { - expect(() => a().ifAbsent(null, 'bar'), throwsArgumentError); - }); - - test('`null` value throws ArgumentError', () { - expect(() => a().ifAbsent('foo', null), throwsArgumentError); - }); }); group('append(String name, String value)', () { @@ -91,14 +78,6 @@ void main() { ..append('foo', 'foo')), ''); }); - - test('`null` name throws ArgumentError', () { - expect(() => a().append(null, 'bar'), throwsArgumentError); - }); - - test('`null` value throws ArgumentError', () { - expect(() => a().append('foo', null), throwsArgumentError); - }); }); group('append(String name, String value, {String separator})', () { @@ -145,14 +124,6 @@ void main() { ..prepend('foo', 'foo')), ''); }); - - test('`null` name throws ArgumentError', () { - expect(() => a().prepend(null, 'bar'), throwsArgumentError); - }); - - test('`null` value throws ArgumentError', () { - expect(() => a().prepend('foo', null), throwsArgumentError); - }); }); group('prepend(String name, String value, {String separator})', () { @@ -199,10 +170,6 @@ void main() { ..remove('bar')), ''); }); - - test('`null` name throws ArgumentError', () { - expect(() => a().remove(null), throwsArgumentError); - }); }); group('fill(Element element))', () { diff --git a/test/whitelist_test.dart b/test/whitelist_test.dart index 8fbfb30..fc17ce4 100644 --- a/test/whitelist_test.dart +++ b/test/whitelist_test.dart @@ -11,11 +11,11 @@ void main() { final basic = simpleText + ' a
blockquote

' - 'citecode
dt
dd
' - 'kbd
  1. olli

p

pre
q' - 'sampsmallspan' - 'strikesubsup' - '
  • ulli
var '; + 'citecode
dt
dd
' + 'kbd
  1. olli

p

pre
q' + 'sampsmallspan' + 'strikesubsup' + '
  • ulli
var '; final basicWithImages = basic + ' '; @@ -26,7 +26,7 @@ void main() { final basicWithImagesContents = ' ' + tooMuchContents; final basicContents = ' ablockquotecitecodedtddkbdollippreqsamp' - 'smallspanstrikesubsupullivar ' + + 'smallspanstrikesubsupullivar ' + basicWithImagesContents; final textContents = ' bemistrongu ' + basicContents; @@ -242,7 +242,7 @@ void main() { Whitelist.none .tags(anyTag) .attributes('a', 'href', - when: (t, a) => a['href'].startsWith('f')) + when: (t, a) => a['href']!.startsWith('f')) .safeCopy('foohash'), 'foohash'); }); @@ -260,7 +260,7 @@ void main() { Whitelist.none .tags(anyTag) .attributes(anyTag, 'href', - when: (t, a) => a['href'].startsWith('f')) + when: (t, a) => a['href']!.startsWith('f')) .safeCopy('foobar'), 'foobar'); });