Version 2.14.0-3.0.dev
Merge commit '17bac2f18068487158b758810894547dcd441dd2' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 1224444..ef7591c 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2021-04-13T11:00:55.084091",
+ "generated": "2021-04-13T13:32:11.977579",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -339,7 +339,7 @@
"name": "http_parser",
"rootUri": "../third_party/pkg/http_parser",
"packageUri": "lib/",
- "languageVersion": "2.11"
+ "languageVersion": "2.12"
},
{
"name": "http_retry",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7c2e449..3441a82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -144,6 +144,12 @@
[#44211]: https://github.com/dart-lang/sdk/issues/44211
+## 2.12.3 - 2021-04-12
+
+This is a patch release that fixes a vulnerability in `dart:html` related to
+DOM clobbering. Thanks again to **Vincenzo di Cicco** for finding and reporting
+this vulnerability.
+
## 2.12.2 - 2021-03-17
This is a patch release that fixes crashes reported by Flutter 2 users (issue
diff --git a/DEPS b/DEPS
index 86b73eb..62dd712 100644
--- a/DEPS
+++ b/DEPS
@@ -110,7 +110,7 @@
"html_rev": "00cd3c22dac0e68e6ed9e7e4945101aedb1b3109",
"http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
"http_multi_server_rev" : "7aca9e87d4a68374b685334f20359320054b8d7b",
- "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
+ "http_parser_rev": "7720bfd42a0c096734c5213478fdce92c62f0293",
"http_retry_rev": "845771af7bb5ab38ab740ce4a31f3b0c7680302b",
"http_rev": "69d6064dd92470ed7ccd50a808fc789ee7716fe8",
"http_throttle_tag" : "1.0.2",
diff --git a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
index 467f323..be674c8 100644
--- a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
@@ -16,4 +16,5 @@
- test/flow_analysis/reachability/data/**
- test/flow_analysis/type_promotion/data/**
- test/flow_analysis/why_not_promoted/data/**
+ - test/inference/inferred_type_arguments/data/**
- test/inheritance/data/**
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 40fcb0f..3288d8b 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -362,7 +362,6 @@
return driver
.getResult(path, sendCachedToStream: sendCachedToStream)
- .then((value) => value.state == ResultState.VALID ? value : null)
.catchError((e, st) {
instrumentationService.logException(e, st);
return null;
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index deca868..fedd848 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -87,6 +87,9 @@
Location _getLocationOffsetLength(int offset, int length) {
var path = resolvedUnit.path;
+ if (path == null) {
+ throw StateError('DartUnitOutlineComputer called with invalid result');
+ }
var startLocation = resolvedUnit.lineInfo.getLocation(offset);
var startLine = startLocation.lineNumber;
var startColumn = startLocation.columnNumber;
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index 8ad83ca..3a2ec51 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -33,7 +33,7 @@
List<ImportedElements> importedElementsList) async {
var unit = libraryResult.unit;
var path = libraryResult.path;
- if (unit == null) {
+ if (unit == null || path == null) {
// We should never reach this point because the libraryResult should be
// valid.
return SourceChange('');
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index c557341..0cec373 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -61,7 +61,7 @@
// Prepare the resolved units.
var result = await server.getResolvedUnit(file);
- if (result == null) {
+ if (result.state != ResultState.VALID) {
server.sendResponse(Response.fileNotAnalyzed(request, file));
return;
}
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index ee2cb5c..7c029d8 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -24,7 +24,7 @@
var context = tracker.getContext(analysisContext);
if (context == null) return;
- var librariesObject = context.getLibraries(resolvedUnit.path);
+ var librariesObject = context.getLibraries(resolvedUnit.path!);
var importedUriSet = resolvedUnit.libraryElement.importedLibraries
.map((importedLibrary) => importedLibrary.source.uri)
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 87310e8..7c20027 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -96,7 +96,7 @@
}) async {
request.checkAborted();
var pathContext = request.resourceProvider.pathContext;
- if (!file_paths.isDart(pathContext, request.result.path)) {
+ if (!file_paths.isDart(pathContext, request.result.path!)) {
return const <CompletionSuggestion>[];
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 9c530a8..d2ce0e3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -700,7 +700,7 @@
ExecutableElement element, bool invokeSuper) async {
var displayTextBuffer = StringBuffer();
var builder = ChangeBuilder(session: request.result.session);
- await builder.addDartFileEdit(request.result.path, (builder) {
+ await builder.addDartFileEdit(request.result.path!, (builder) {
builder.addReplacement(range.node(targetId), (builder) {
builder.writeOverride(
element,
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index 988a42d..8aa88e2 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
@@ -264,7 +264,7 @@
String get eol => utils.endOfLine;
- String get file => completionContext.resolveResult.path;
+ String get file => completionContext.resolveResult.path!;
String get key => completionContext.key;
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index e71629b..9bd0039 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -120,7 +120,7 @@
String get eol => utils.endOfLine;
- String get file => statementContext.resolveResult.path;
+ String get file => statementContext.resolveResult.path!;
LineInfo get lineInfo => statementContext.resolveResult.lineInfo;
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index fb8a04f..543d8c9 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -33,7 +33,7 @@
this.selectionLength = 0,
required this.resolvedResult,
required this.workspace,
- }) : file = resolvedResult.path,
+ }) : file = resolvedResult.path!,
session = resolvedResult.session,
sessionHelper = AnalysisSessionHelper(resolvedResult.session),
typeProvider = resolvedResult.typeProvider,
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 50132d8..65467c5 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -281,7 +281,7 @@
/// library associated with the analysis [result].
Future<void> _fixErrorsInLibrary(ResolvedLibraryResult result) async {
var analysisOptions = result.session.analysisContext.analysisOptions;
- for (var unitResult in result.units) {
+ for (var unitResult in result.units!) {
var overrideSet = _readOverrideSet(unitResult);
for (var error in unitResult.errors) {
var processor = ErrorProcessor.getProcessor(analysisOptions, error);
@@ -348,7 +348,7 @@
await compute(producer);
var newHash = computeChangeHash();
if (newHash != oldHash) {
- changeMap.add(result.path, code);
+ changeMap.add(result.path!, code);
}
}
@@ -398,7 +398,7 @@
if (useConfigFiles) {
var provider = result.session.resourceProvider;
var context = provider.pathContext;
- var dartFileName = result.path;
+ var dartFileName = result.path!;
var configFileName = '${context.withoutExtension(dartFileName)}.config';
var configFile = provider.getFile(configFileName);
try {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 7241c32..a39cc31 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -248,7 +248,7 @@
this.overrideSet,
this.selectionOffset = -1,
this.selectionLength = 0,
- }) : file = resolvedResult.path,
+ }) : file = resolvedResult.path!,
session = resolvedResult.session,
sessionHelper = AnalysisSessionHelper(resolvedResult.session),
typeProvider = resolvedResult.typeProvider,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart
index c841c0f..0f22239 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart
@@ -27,7 +27,7 @@
}
var libraryPath = resolvedResult.libraryElement.source.fullName;
- var partPath = resolvedResult.path;
+ var partPath = resolvedResult.path!;
var relativePath = relative(libraryPath, from: dirname(partPath));
var uri = Uri.file(relativePath).toString();
var replacementRange = range.node(libraryName);
diff --git a/pkg/analysis_server/lib/src/services/flutter/property.dart b/pkg/analysis_server/lib/src/services/flutter/property.dart
index 0d4f3e3..11af175 100644
--- a/pkg/analysis_server/lib/src/services/flutter/property.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/property.dart
@@ -118,7 +118,7 @@
);
}
- await builder.addDartFileEdit(resolvedUnit.path, (builder) {
+ await builder.addDartFileEdit(resolvedUnit.path!, (builder) {
_changeCode(builder, (builder) {
var expression = value.expression;
if (expression != null) {
@@ -155,7 +155,7 @@
}
var beginOffset = argumentExpression.offset;
- await builder.addDartFileEdit(resolvedUnit.path, (builder) {
+ await builder.addDartFileEdit(resolvedUnit.path!, (builder) {
builder.addDeletion(
SourceRange(beginOffset, endOffset - beginOffset),
);
@@ -559,7 +559,7 @@
var builder = ChangeBuilder(session: property.resolvedUnit.session);
- await builder.addDartFileEdit(property.resolvedUnit.path, (builder) {
+ await builder.addDartFileEdit(property.resolvedUnit.path!, (builder) {
property._changeCode(builder, (builder) {
if (leftCode == rightCode && topCode == bottomCode) {
builder.writeReference(classEdgeInsets);
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index 822589b..e81ca0e 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -30,6 +30,7 @@
handler = EditDomainHandler(server);
}
+ @failingTest
Future test_BAD_doesNotExist() async {
// The analysis driver fails to return an error
var request =
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 4320775..850b29a 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -360,7 +360,7 @@
Map<String, FileResult> fileResults = {};
void addFileResult(FileResult result) {
- fileResults[result.path] = result;
+ fileResults[result.path!] = result;
}
@override
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 6c36a21..4a17594 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -17,7 +17,9 @@
abstract class AnalysisResult {
/// The absolute and normalized path of the file that was analyzed.
/// If [state] is not [ResultState.VALID], throws [StateError].
- String get path;
+ ///
+ /// TODO(migration): should not be nullable
+ String? get path;
/// Return the session used to compute this result.
/// If [state] is not [ResultState.VALID], throws [StateError].
@@ -84,13 +86,13 @@
/// Clients may not extend, implement or mix-in this class.
abstract class ParsedLibraryResult implements AnalysisResult {
/// The parsed units of the library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
- List<ParsedUnitResult> get units;
+ ///
+ /// TODO(migration): should not be null, probably empty list
+ List<ParsedUnitResult>? get units;
/// Return the declaration of the [element], or `null` if the [element]
/// is synthetic. Throw [ArgumentError] if the [element] is not defined in
/// this library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
ElementDeclarationResult? getElementDeclaration(Element element);
}
@@ -132,21 +134,17 @@
/// Clients may not extend, implement or mix-in this class.
abstract class ResolvedLibraryResult implements AnalysisResult {
/// The element representing this library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
- LibraryElement get element;
+ LibraryElement? get element;
/// The type provider used when resolving the library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
TypeProvider get typeProvider;
/// The resolved units of the library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
- List<ResolvedUnitResult> get units;
+ List<ResolvedUnitResult>? get units;
/// Return the declaration of the [element], or `null` if the [element]
/// is synthetic. Throw [ArgumentError] if the [element] is not defined in
/// this library.
- /// If [state] is not [ResultState.VALID], throws [StateError].
ElementDeclarationResult? getElementDeclaration(Element element);
}
@@ -173,10 +171,6 @@
/// An indication of whether an analysis result is valid, and if not why.
enum ResultState {
- /// An indication that the analysis result cannot be provided because
- /// the library is created from summary.
- EXTERNAL_LIBRARY,
-
/// An indication that analysis could not be performed because the path
/// represents a file of a type that cannot be analyzed.
INVALID_FILE_TYPE,
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 0317cd7..ef61719 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -851,7 +851,6 @@
StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK,
StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE,
StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
- StrongModeCode.TOP_LEVEL_INSTANCE_METHOD,
TodoCode.TODO,
];
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 75f297c..8f17b48 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -215,7 +215,7 @@
final _resultController = StreamController<ResolvedUnitResult>();
/// The stream that will be written to when analysis results are produced.
- late final Stream<ResolvedUnitResult> _resultStream;
+ late final Stream<ResolvedUnitResult> _onResults;
/// Resolution signatures of the most recently produced results for files.
final Map<String, String> _lastProducedSignatures = {};
@@ -282,7 +282,7 @@
_externalSummaries = externalSummaries,
testingData = retainDataForTesting ? TestingData() : null {
_createNewSession(null);
- _resultStream = _resultController.stream.asBroadcastStream();
+ _onResults = _resultController.stream.asBroadcastStream();
_testView = AnalysisDriverTestView(this);
_createFileTracker();
_scheduler.add(this);
@@ -361,7 +361,7 @@
///
/// Results might be produced even for files that have never been added
/// using [addFile], for example when [getResult] was called for a file.
- Stream<ResolvedUnitResult> get results => _resultStream;
+ Stream<ResolvedUnitResult> get results => _onResults;
/// Return the search support for the driver.
Search get search => _search;
@@ -649,7 +649,7 @@
FileState file = _fsState.getFileForPath(path);
if (file.isExternalLibrary) {
- return NotValidParsedLibraryResultImpl(ResultState.EXTERNAL_LIBRARY);
+ return ParsedLibraryResultImpl.external(currentSession, file.uri);
}
if (file.isPart) {
@@ -680,7 +680,7 @@
}
if (file.isExternalLibrary) {
- return NotValidParsedLibraryResultImpl(ResultState.EXTERNAL_LIBRARY);
+ return ParsedLibraryResultImpl.external(currentSession, file.uri);
}
if (file.isPart) {
@@ -718,7 +718,7 @@
if (file.isExternalLibrary) {
return Future.value(
- NotValidResolvedLibraryResultImpl(ResultState.EXTERNAL_LIBRARY),
+ ResolvedLibraryResultImpl.external(currentSession, file.uri),
);
}
@@ -756,7 +756,7 @@
if (file.isExternalLibrary) {
return Future.value(
- NotValidResolvedLibraryResultImpl(ResultState.EXTERNAL_LIBRARY),
+ ResolvedLibraryResultImpl.external(currentSession, file.uri),
);
}
@@ -1102,7 +1102,7 @@
// last time, so we don't need to produce it again now.
} else {
_resultController.add(result);
- _lastProducedSignatures[result.path] = result._signature;
+ _lastProducedSignatures[result.path!] = result._signature;
}
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index 1f4ded0..c2e5b28 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -18,7 +18,7 @@
final AnalysisSession session;
@override
- final String path;
+ final String? path;
@override
final Uri uri;
@@ -75,7 +75,7 @@
NotValidAnalysisResultImpl(this.state);
@override
- String get path {
+ String? get path {
throw StateError('This result is not valid');
}
@@ -117,46 +117,6 @@
}
}
-class NotValidParsedLibraryResultImpl extends NotValidAnalysisResultImpl
- implements ParsedLibraryResult {
- NotValidParsedLibraryResultImpl(ResultState state) : super(state);
-
- @override
- List<ParsedUnitResult> get units {
- throw StateError('This result is not valid');
- }
-
- @override
- ElementDeclarationResult? getElementDeclaration(Element element) {
- throw StateError('This result is not valid');
- }
-}
-
-class NotValidResolvedLibraryResultImpl extends NotValidAnalysisResultImpl
- implements ResolvedLibraryResult {
- NotValidResolvedLibraryResultImpl(ResultState state) : super(state);
-
- @override
- LibraryElement get element {
- throw StateError('This result is not valid');
- }
-
- @override
- TypeProvider get typeProvider {
- throw StateError('This result is not valid');
- }
-
- @override
- List<ResolvedUnitResult> get units {
- throw StateError('This result is not valid');
- }
-
- @override
- ElementDeclarationResult? getElementDeclaration(Element element) {
- throw StateError('This result is not valid');
- }
-}
-
/// The implementation of [ResolvedUnitResult] when not [ResultState.VALID].
class NotValidResolvedUnitResultImpl extends NotValidFileResultImpl
implements ResolvedUnitResult {
@@ -212,14 +172,20 @@
class ParsedLibraryResultImpl extends AnalysisResultImpl
implements ParsedLibraryResult {
@override
- final List<ParsedUnitResult> units;
+ final List<ParsedUnitResult>? units;
ParsedLibraryResultImpl(
- AnalysisSession session, String path, Uri uri, this.units)
+ AnalysisSession session, String? path, Uri uri, this.units)
: super(session, path, uri);
+ ParsedLibraryResultImpl.external(AnalysisSession session, Uri uri)
+ : this(session, null, uri, null);
+
@override
ResultState get state {
+ if (path == null) {
+ return ResultState.NOT_A_FILE;
+ }
return ResultState.VALID;
}
@@ -237,7 +203,7 @@
}
var elementPath = element.source!.fullName;
- var unitResult = units.firstWhere(
+ var unitResult = units!.firstWhere(
(r) => r.path == elementPath,
orElse: () {
var elementStr = element.getDisplayString(withNullability: true);
@@ -295,22 +261,28 @@
class ResolvedLibraryResultImpl extends AnalysisResultImpl
implements ResolvedLibraryResult {
@override
- final LibraryElement element;
+ final LibraryElement? element;
@override
- final List<ResolvedUnitResult> units;
+ final List<ResolvedUnitResult>? units;
ResolvedLibraryResultImpl(
- AnalysisSession session, String path, Uri uri, this.element, this.units)
+ AnalysisSession session, String? path, Uri uri, this.element, this.units)
: super(session, path, uri);
+ ResolvedLibraryResultImpl.external(AnalysisSession session, Uri uri)
+ : this(session, null, uri, null, null);
+
@override
ResultState get state {
+ if (path == null) {
+ return ResultState.NOT_A_FILE;
+ }
return ResultState.VALID;
}
@override
- TypeProvider get typeProvider => element.typeProvider;
+ TypeProvider get typeProvider => element!.typeProvider;
@override
ElementDeclarationResult? getElementDeclaration(Element element) {
@@ -326,7 +298,7 @@
}
var elementPath = element.source!.fullName;
- var unitResult = units.firstWhere(
+ var unitResult = units!.firstWhere(
(r) => r.path == elementPath,
orElse: () {
var elementStr = element.getDisplayString(withNullability: true);
@@ -335,7 +307,7 @@
buffer.writeln(' is not defined in this library.');
// TODO(scheglov) https://github.com/dart-lang/sdk/issues/45430
buffer.writeln('elementPath: $elementPath');
- buffer.writeln('unitPaths: ${units.map((e) => e.path).toList()}');
+ buffer.writeln('unitPaths: ${units!.map((e) => e.path).toList()}');
throw ArgumentError('$buffer');
},
);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
index d65da13..235e67d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
@@ -54,7 +54,7 @@
var resolvedLibrary = await _getResolvedLibrary(libraryPath);
var unitPath = element.source!.fullName;
- return resolvedLibrary.units.singleWhere((resolvedUnit) {
+ return resolvedLibrary.units!.singleWhere((resolvedUnit) {
return resolvedUnit.path == unitPath;
});
}
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index fb17e85..e7dff9b 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -398,7 +398,7 @@
performance: performance,
);
var result =
- libraryUnit.units.firstWhere((element) => element.path == path);
+ libraryUnit.units!.firstWhere((element) => element.path == path);
return result;
});
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 58fcf57..bf643c4 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -14223,13 +14223,6 @@
"getter, '{1}', which has an implicit type.",
correction: "Add an explicit type for either '{0}' or '{1}'.");
- static const StrongModeCode TOP_LEVEL_INSTANCE_METHOD = StrongModeCode(
- ErrorType.STATIC_WARNING,
- 'TOP_LEVEL_INSTANCE_METHOD',
- "The type of '{0}' can't be inferred because it refers to an instance "
- "method, '{1}', which has an implicit type.",
- correction: "Add an explicit type for either '{0}' or '{1}'.");
-
@override
final ErrorType type;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index e4fea47..ee2b7f3 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1029,14 +1029,6 @@
_codeChecker._recordMessage(
n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [_name, e.name]);
}
- } else if (!isMethodCall &&
- e is ExecutableElement &&
- e.kind == ElementKind.METHOD &&
- !e.isStatic) {
- if (_hasAnyImplicitType(e)) {
- _codeChecker._recordMessage(
- n, StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, e.name]);
- }
}
}
}
@@ -1135,19 +1127,7 @@
var method = node.methodName.staticElement;
validateIdentifierElement(node, method, isMethodCall: true);
if (method is ExecutableElement) {
- if (method.kind == ElementKind.METHOD &&
- !method.isStatic &&
- method.hasImplicitReturnType) {
- _codeChecker._recordMessage(node,
- StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, method.name]);
- }
if (node.typeArguments == null && method.typeParameters.isNotEmpty) {
- if (method.kind == ElementKind.METHOD &&
- !method.isStatic &&
- _anyParameterHasImplicitType(method)) {
- _codeChecker._recordMessage(node,
- StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, method.name]);
- }
// Type inference might depend on the parameters
node.argumentList.accept(this);
}
@@ -1179,16 +1159,4 @@
visitThrowExpression(ThrowExpression node) {
// Nothing to validate.
}
-
- bool _anyParameterHasImplicitType(ExecutableElement e) {
- for (var parameter in e.parameters) {
- if (parameter.hasImplicitType) return true;
- }
- return false;
- }
-
- bool _hasAnyImplicitType(ExecutableElement e) {
- if (e.hasImplicitReturnType) return true;
- return _anyParameterHasImplicitType(e);
- }
}
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index c285f9b..5b8847d 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -497,7 +497,7 @@
var expression = findNode.variableDeclaration('x =').initializer!;
- var file = getFile(result.path);
+ var file = getFile(result.path!);
var evaluator = ConstantEvaluator(
file.createSource(result.uri),
result.libraryElement as LibraryElementImpl,
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
index 978ea99..3eec88f 100644
--- a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
@@ -138,7 +138,7 @@
Future<List<CompilationUnit>> _resolveLibrary(String libraryPath) async {
var session = contextFor(libraryPath).currentSession;
var resolvedLibrary = await session.getResolvedLibrary(libraryPath);
- return resolvedLibrary.units.map((ru) => ru.unit!).toList();
+ return resolvedLibrary.units!.map((ru) => ru.unit!).toList();
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 6572ba2..9ddda1e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -3063,7 +3063,7 @@
driver.changeFile(b);
await waitForIdleWithoutExceptions();
- List<String> analyzedPaths = allResults.map((r) => r.path).toList();
+ List<String> analyzedPaths = allResults.map((r) => r.path!).toList();
// The changed file must be the first.
expect(analyzedPaths[0], b);
@@ -3105,7 +3105,7 @@
driver.changeFile(a);
await waitForIdleWithoutExceptions();
- List<String> analyzedPaths = allResults.map((r) => r.path).toList();
+ List<String> analyzedPaths = allResults.map((r) => r.path!).toList();
// The changed files must be the first.
expect(analyzedPaths[0], a);
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index c32728a..f1235ca 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -175,7 +175,7 @@
expect(parsedLibrary.units, hasLength(1));
{
- var parsedUnit = parsedLibrary.units[0];
+ var parsedUnit = parsedLibrary.units![0];
expect(parsedUnit.session, session);
expect(parsedUnit.path, testPath);
expect(parsedUnit.uri, Uri.parse('package:test/test.dart'));
@@ -249,15 +249,15 @@
expect(parsedLibrary.units, hasLength(3));
expect(
- parsedLibrary.units[0].path,
+ parsedLibrary.units![0].path,
convertPath('/home/test/lib/test.dart'),
);
expect(
- parsedLibrary.units[1].path,
+ parsedLibrary.units![1].path,
convertPath('/home/test/lib/a.dart'),
);
expect(
- parsedLibrary.units[2].path,
+ parsedLibrary.units![2].path,
convertPath('/home/test/lib/c.dart'),
);
}
@@ -307,21 +307,21 @@
expect(parsedLibrary.units, hasLength(3));
{
- var aUnit = parsedLibrary.units[0];
+ var aUnit = parsedLibrary.units![0];
expect(aUnit.path, a);
expect(aUnit.uri, Uri.parse('package:test/a.dart'));
expect(aUnit.unit.declarations, hasLength(1));
}
{
- var bUnit = parsedLibrary.units[1];
+ var bUnit = parsedLibrary.units![1];
expect(bUnit.path, b);
expect(bUnit.uri, Uri.parse('package:test/b.dart'));
expect(bUnit.unit.declarations, hasLength(2));
}
{
- var cUnit = parsedLibrary.units[2];
+ var cUnit = parsedLibrary.units![2];
expect(cUnit.path, c);
expect(cUnit.uri, Uri.parse('package:test/c.dart'));
expect(cUnit.unit.declarations, hasLength(3));
@@ -393,13 +393,13 @@
var typeProvider = resolvedLibrary.typeProvider;
expect(typeProvider.intType.element.name, 'int');
- var libraryElement = resolvedLibrary.element;
+ var libraryElement = resolvedLibrary.element!;
var aClass = libraryElement.getType('A')!;
var bClass = libraryElement.getType('B')!;
- var aUnitResult = resolvedLibrary.units[0];
+ var aUnitResult = resolvedLibrary.units![0];
expect(aUnitResult.path, a);
expect(aUnitResult.uri, Uri.parse('package:test/a.dart'));
expect(aUnitResult.content, aContent);
@@ -408,7 +408,7 @@
expect(aUnitResult.unit!.declarations, hasLength(1));
expect(aUnitResult.errors, isEmpty);
- var bUnitResult = resolvedLibrary.units[1];
+ var bUnitResult = resolvedLibrary.units![1];
expect(bUnitResult.path, b);
expect(bUnitResult.uri, Uri.parse('package:test/b.dart'));
expect(bUnitResult.content, bContent);
@@ -449,7 +449,7 @@
''');
var resolvedLibrary = await session.getResolvedLibrary(testPath);
- var unitElement = resolvedLibrary.element.definingCompilationUnit;
+ var unitElement = resolvedLibrary.element!.definingCompilationUnit;
var fooElement = unitElement.topLevelVariables[0];
expect(fooElement.name, 'foo');
@@ -478,15 +478,15 @@
expect(resolvedLibrary.units, hasLength(3));
expect(
- resolvedLibrary.units[0].path,
+ resolvedLibrary.units![0].path,
convertPath('/home/test/lib/test.dart'),
);
expect(
- resolvedLibrary.units[1].path,
+ resolvedLibrary.units![1].path,
convertPath('/home/test/lib/a.dart'),
);
expect(
- resolvedLibrary.units[2].path,
+ resolvedLibrary.units![2].path,
convertPath('/home/test/lib/c.dart'),
);
}
@@ -509,7 +509,7 @@
expect(resolvedLibrary.path, testPath);
expect(resolvedLibrary.uri, Uri.parse('package:test/test.dart'));
expect(resolvedLibrary.units, hasLength(1));
- expect(resolvedLibrary.units[0].unit!.declaredElement, isNotNull);
+ expect(resolvedLibrary.units![0].unit!.declaredElement, isNotNull);
}
test_getResolvedLibraryByElement_differentSession() async {
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 54c65b5..aa6dfb3 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -700,7 +700,7 @@
var result = fileResolver.resolveLibrary(path: aPath);
expect(result.path, aPath);
- expect(result.units.length, 2);
+ expect(result.units?.length, 2);
}
test_reuse_compatibleOptions() async {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 6bd56ae..3d1234d 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -607,7 +607,6 @@
import 'todo_test.dart' as todo_test;
import 'top_level_cycle_test.dart' as top_level_cycle;
import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
-import 'top_level_instance_method_test.dart' as top_level_instance_method;
import 'type_alias_cannot_reference_itself_test.dart'
as type_alias_cannot_reference_itself;
import 'type_annotation_deferred_class_test.dart'
@@ -1087,7 +1086,6 @@
todo_test.main();
top_level_cycle.main();
top_level_instance_getter.main();
- top_level_instance_method.main();
type_alias_cannot_reference_itself.main();
type_annotation_deferred_class.main();
type_argument_not_matching_bounds.main();
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
deleted file mode 100644
index b71dd5b..0000000
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/error/codes.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/context_collection_resolution.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(TopLevelInstanceMethodTest);
- });
-}
-
-@reflectiveTest
-class TopLevelInstanceMethodTest extends PubPackageResolutionTest {
- test_noParameter() async {
- await assertErrorsInCode('''
-class A {
- f() => 0;
-}
-var x = new A().f();
-''', [
- error(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, 32, 11),
- ]);
- }
-
- test_parameter() async {
- await assertNoErrorsInCode('''
-class A {
- int f(v) => 0;
-}
-var x = new A().f(0);
-''');
- }
-
- test_parameter_generic() async {
- await assertErrorsInCode('''
-class A {
- int f<T>(v) => 0;
-}
-var x = new A().f(0);
-''', [
- error(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, 40, 12),
- ]);
- }
-
- test_parameter_generic_explicit() async {
- await assertNoErrorsInCode('''
-class A {
- int f<T>(v) => 0;
-}
-var x = new A().f<int>(0);
-''');
- }
-
- test_static() async {
- await assertNoErrorsInCode('''
-class A {
- static f() => 0;
-}
-var x = A.f();
-''');
- }
-
- test_tearOff() async {
- await assertErrorsInCode('''
-class A {
- f() => 0;
-}
-var x = new A().f;
-''', [
- error(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, 40, 1),
- ]);
- }
-
- test_tearOff_parameter() async {
- await assertErrorsInCode('''
-class A {
- int f(v) => 0;
-}
-var x = new A().f;
-''', [
- error(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, 45, 1),
- ]);
- }
-
- test_tearoff_static() async {
- await assertNoErrorsInCode('''
-class A {
- static f() => 0;
-}
-var x = A.f;
-''');
- }
-}
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index fc25b65..212b95b 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -804,6 +804,29 @@
''');
}
+ test_initializer_fromInstanceMethod() async {
+ var library = await _encodeDecodeLibrary(r'''
+class A {
+ int foo() => 0;
+}
+class B extends A {
+ foo() => 1;
+}
+var x = A().foo();
+var y = B().foo();
+''');
+ checkElementText(library, r'''
+class A {
+ int foo() {}
+}
+class B extends A {
+ int foo() {}
+}
+int x;
+int y;
+''');
+ }
+
test_initializer_functionExpression() async {
var library = await _encodeDecodeLibrary(r'''
import 'dart:async';
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index cc1d282..d77818f 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -2560,7 +2560,7 @@
}
test_infer_use_of_void() async {
- await assertErrorsInCode('''
+ await assertNoErrorsInCode('''
class B {
void f() {}
}
@@ -2568,9 +2568,8 @@
f() {}
}
var x = new C().f();
-''', [
- error(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, 65, 11),
- ]);
+''');
+ assertType(findElement.topVar('x').type, 'void');
}
test_inferConstsTransitively() async {
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 8fdbc40..f99f600 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -285,7 +285,7 @@
/// Extract documentation from the file that was parsed to produce the given
/// [result].
Future<void> _validateFile(ParsedUnitResult result) async {
- filePath = result.path;
+ filePath = result.path!;
hasWrittenFilePath = false;
CompilationUnit unit = result.unit;
for (CompilationUnitMember declaration in unit.declarations) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index dc60a78..443c711 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1281,7 +1281,7 @@
/// the given [resolvedUnit] and [timeStamp].
DartFileEditBuilderImpl(ChangeBuilderImpl changeBuilder, this.resolvedUnit,
int timeStamp, this.libraryChangeBuilder)
- : super(changeBuilder, resolvedUnit.path, timeStamp);
+ : super(changeBuilder, resolvedUnit.path!, timeStamp);
@override
bool get hasEdits =>
diff --git a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
index d424abf..a302a76 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
@@ -21,7 +21,7 @@
DartFoldingRequestImpl(this.resourceProvider, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [FoldingCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
index 95bd889..5e55b48 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
@@ -21,7 +21,7 @@
DartHighlightsRequestImpl(this.resourceProvider, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [HighlightsCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
index 684e9e7..191101c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
@@ -19,7 +19,7 @@
DartEntryRequestImpl(this.resourceProvider, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [EntryCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
index 23709a3..4e1850c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
@@ -28,7 +28,7 @@
this.resourceProvider, this.offset, this.length, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [NavigationCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
index f436774..6bd0592 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
@@ -20,7 +20,7 @@
DartOccurrencesRequestImpl(this.resourceProvider, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [OccurrencesCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
index 284f140..44d4dd9 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
@@ -20,7 +20,7 @@
DartOutlineRequestImpl(this.resourceProvider, this.result);
@override
- String get path => result.path;
+ String get path => result.path!;
}
/// A concrete implementation of [OutlineCollector].
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 977a16c..0dfdbc8 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -16545,7 +16545,7 @@
String? get status native;
- FontFaceSet add(FontFace arg) native;
+ FontFaceSet? add(FontFace arg) native;
bool check(String font, [String? text]) native;
@@ -40994,8 +40994,8 @@
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
NodeValidator validator;
- /// Did we modify the tree by removing anything.
- bool modifiedTree = false;
+ /// Number of tree modifications this instance has made.
+ int numTreeModifications = 0;
_ValidatingTreeSanitizer(this.validator) {}
void sanitizeTree(Node node) {
@@ -41026,12 +41026,12 @@
}
}
- modifiedTree = false;
- walk(node, null);
- while (modifiedTree) {
- modifiedTree = false;
+ // Walk the tree until no new modifications are added to the tree.
+ var previousTreeModifications;
+ do {
+ previousTreeModifications = numTreeModifications;
walk(node, null);
- }
+ } while (previousTreeModifications != numTreeModifications);
}
/// Aggressively try to remove node.
@@ -41039,7 +41039,7 @@
// If we have the parent, it's presumably already passed more sanitization
// or is the fragment, so ask it to remove the child. And if that fails
// try to set the outer html.
- modifiedTree = true;
+ numTreeModifications++;
if (parent == null || parent != node.parentNode) {
node.remove();
} else {
diff --git a/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
index 5a3d0f2..2d7205c 100644
--- a/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
+++ b/tests/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -453,6 +453,20 @@
"<input id='bad' onmouseover='alert(1)'>",
"");
+ // Walking templates triggers a recursive sanitization call, which shouldn't
+ // invalidate the information collected from the previous visit of the later
+ // nodes in the walk.
+ testHtml(
+ 'DOM clobbering with recursive sanitize call using templates',
+ validator,
+ "<form><div>"
+ "<input id=childNodes />"
+ "<template></template>"
+ "<input id=childNodes name=lastChild />"
+ "<img id=exploitImg src=0 onerror='alert(1)' />"
+ "</div></form>",
+ "");
+
test('tagName makes containing form invalid', () {
var fragment = document.body!.createFragment(
"<form onmouseover='alert(2)'><input name='tagName'>",
diff --git a/tests/lib_2/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/lib_2/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
index 1b3ea60..ee31868 100644
--- a/tests/lib_2/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
+++ b/tests/lib_2/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -478,6 +478,20 @@
"<input id='bad' onmouseover='alert(1)'>",
"");
+ // Walking templates triggers a recursive sanitization call, which shouldn't
+ // invalidate the information collected from the previous visit of the later
+ // nodes in the walk.
+ testHtml(
+ 'DOM clobbering with recursive sanitize call using templates',
+ validator,
+ "<form><div>"
+ "<input id=childNodes />"
+ "<template></template>"
+ "<input id=childNodes name=lastChild />"
+ "<img id=exploitImg src=0 onerror='alert(1)' />"
+ "</div></form>",
+ "");
+
test('tagName makes containing form invalid', () {
var fragment = document.body.createFragment(
"<form onmouseover='alert(2)'><input name='tagName'>",
diff --git a/tools/VERSION b/tools/VERSION
index baa7861..9201ef4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 2
+PRERELEASE 3
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index 475b759..4518982 100644
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -796,7 +796,11 @@
return syn_op
-def generate_operation(interface_name, result_type_name, oper_name, arguments):
+def generate_operation(interface_name,
+ result_type_name,
+ oper_name,
+ arguments,
+ result_nullable=False):
""" Synthesize an IDLOperation with no AST used for support of setlike."""
""" Arguments is a list of argument where each argument is:
[IDLType, argument_name, optional_boolean] """
@@ -805,6 +809,7 @@
syn_op.type = IDLType(None, result_type_name)
syn_op.type = resolveTypedef(syn_op.type)
+ syn_op.type.nullable = result_nullable
for argument in arguments:
arg = IDLArgument(None, argument[1])
@@ -854,9 +859,13 @@
setlike_ops.append(set_op)
if not set_like.is_read_only:
+ # Issue #45676: `add` can return null on Firefox, so this should be
+ # typed nullable.
+ add_result_nullable = True
set_op = generate_operation(
interface.id, interface.id, 'add',
- [[IDLType(None, set_like.value_type.base_type), 'arg']])
+ [[IDLType(None, set_like.value_type.base_type), 'arg']],
+ add_result_nullable)
setlike_ops.append(set_op)
set_op = generate_operation(
interface.id, 'boolean', 'delete',
diff --git a/tools/dom/src/Validators.dart b/tools/dom/src/Validators.dart
index 0c45b8c..1fbafbd 100644
--- a/tools/dom/src/Validators.dart
+++ b/tools/dom/src/Validators.dart
@@ -158,8 +158,8 @@
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
NodeValidator validator;
- /// Did we modify the tree by removing anything.
- bool modifiedTree = false;
+ /// Number of tree modifications this instance has made.
+ int numTreeModifications = 0;
_ValidatingTreeSanitizer(this.validator) {}
void sanitizeTree(Node node) {
@@ -190,12 +190,12 @@
}
}
- modifiedTree = false;
- walk(node, null);
- while (modifiedTree) {
- modifiedTree = false;
+ // Walk the tree until no new modifications are added to the tree.
+ var previousTreeModifications;
+ do {
+ previousTreeModifications = numTreeModifications;
walk(node, null);
- }
+ } while (previousTreeModifications != numTreeModifications);
}
/// Aggressively try to remove node.
@@ -203,7 +203,7 @@
// If we have the parent, it's presumably already passed more sanitization
// or is the fragment, so ask it to remove the child. And if that fails
// try to set the outer html.
- modifiedTree = true;
+ numTreeModifications++;
if (parent == null || parent != node.parentNode) {
node.remove();
} else {