Sanitize arguments of super/redirecting constructor invocations.

We have a spike of crashes internally.

Change-Id: If7c280692ac0acdd2e4a4acd6096a4669746069c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291120
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-03-24 21:42:37 +00:00 committed by Commit Queue
parent edccf64f54
commit 84c0f2c880
3 changed files with 100 additions and 9 deletions

View file

@ -87,7 +87,7 @@ import 'package:analyzer/src/utilities/uri_cache.dart';
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 264;
static const int DATA_VERSION = 265;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.

View file

@ -39,6 +39,10 @@ class _Visitor extends GeneralizingElementVisitor<void> {
final expression = initializer.expression;
final replacement = replaceNotSerializableNode(expression);
initializer.expression = replacement;
} else if (initializer is RedirectingConstructorInvocationImpl) {
_sanitizeArguments(initializer.argumentList.arguments);
} else if (initializer is SuperConstructorInvocationImpl) {
_sanitizeArguments(initializer.argumentList.arguments);
}
}
@ -52,13 +56,7 @@ class _Visitor extends GeneralizingElementVisitor<void> {
for (final annotation in element.metadata) {
final ast = (annotation as ElementAnnotationImpl).annotationAst;
_detachNode(ast);
// Sanitize arguments.
final arguments = ast.arguments?.arguments;
if (arguments != null) {
for (var i = 0; i < arguments.length; i++) {
arguments[i] = replaceNotSerializableNode(arguments[i]);
}
}
_sanitizeArguments(ast.arguments?.arguments);
}
super.visitElement(element);
}
@ -108,4 +106,12 @@ class _Visitor extends GeneralizingElementVisitor<void> {
node.endToken.next = null;
}
}
void _sanitizeArguments(List<ExpressionImpl>? arguments) {
if (arguments != null) {
for (var i = 0; i < arguments.length; i++) {
arguments[i] = replaceNotSerializableNode(arguments[i]);
}
}
}
}

View file

@ -12911,7 +12911,7 @@ library
''');
}
test_const_invalid_functionExpression_inConstructorInitializer() async {
test_const_invalid_functionExpression_constructorFieldInitializer() async {
var library = await buildLibrary('''
class A {
final Object? foo;
@ -12968,6 +12968,91 @@ library
''');
}
test_const_invalid_functionExpression_redirectingConstructorInvocation() async {
var library = await buildLibrary('''
class A {
const A(Object a, Object b);
const A.named() : this(0, () => 0);
}
''');
checkElementText(library, r'''
library
definingUnit
classes
class A @6
constructors
const @18
parameters
requiredPositional a @27
type: Object
requiredPositional b @37
type: Object
const named @51
periodOffset: 50
nameEnd: 56
constantInitializers
RedirectingConstructorInvocation
thisKeyword: this @61
argumentList: ArgumentList
leftParenthesis: ( @65
arguments
IntegerLiteral
literal: 0 @66
staticType: int
SimpleIdentifier
token: _notSerializableExpression @-1
staticElement: <null>
staticType: null
rightParenthesis: ) @76
staticElement: self::@class::A::@constructor::new
redirectedConstructor: self::@class::A::@constructor::new
''');
}
test_const_invalid_functionExpression_superConstructorInvocation() async {
var library = await buildLibrary('''
class A {
const A(Object a, Object b);
}
class B extends A {
const B() : super(0, () => 0);
}
''');
checkElementText(library, r'''
library
definingUnit
classes
class A @6
constructors
const @18
parameters
requiredPositional a @27
type: Object
requiredPositional b @37
type: Object
class B @49
supertype: A
constructors
const @71
constantInitializers
SuperConstructorInvocation
superKeyword: super @77
argumentList: ArgumentList
leftParenthesis: ( @82
arguments
IntegerLiteral
literal: 0 @83
staticType: int
SimpleIdentifier
token: _notSerializableExpression @-1
staticElement: <null>
staticType: null
rightParenthesis: ) @93
staticElement: self::@class::A::@constructor::new
superConstructor: self::@class::A::@constructor::new
''');
}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
test_const_invalid_intLiteral() async {
var library = await buildLibrary(r'''