Skip to content

Commit 0f6928c

Browse files
johnniwintherCommit Queue
authored andcommitted
[kerne] Add verification of annotation nodes
This adds verification of annotation nodes after constant evaluation should only be ConstantExpression or InvalidExpression. Prompted by #62096 which crashes from an unexpected annotation expression, like an InvalidExpression. Change-Id: I91b723f3804694dd317396e2a7a80d50a06b225d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/465040 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent eb1a814 commit 0f6928c

File tree

1 file changed

+63
-9
lines changed

1 file changed

+63
-9
lines changed

pkg/kernel/lib/verifier.dart

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,17 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
417417
enterTreeNode(node);
418418
fileUri = checkLocation(node, node.name, node.fileUri);
419419
currentLibrary = node;
420-
super.visitLibrary(node);
420+
TreeNode? oldParent = enterParent(node);
421+
_visitAnnotations(node.annotations);
422+
visitList(node.dependencies, this);
423+
visitList(node.parts, this);
424+
visitList(node.typedefs, this);
425+
visitList(node.classes, this);
426+
visitList(node.extensions, this);
427+
visitList(node.extensionTypeDeclarations, this);
428+
visitList(node.procedures, this);
429+
visitList(node.fields, this);
430+
exitParent(oldParent);
421431
currentLibrary = null;
422432
exitTreeNode(node);
423433
_extensionsMembers = null;
@@ -465,6 +475,25 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
465475
return _extensionsMembers!;
466476
}
467477

478+
@override
479+
void visitLibraryPart(LibraryPart node) {
480+
enterTreeNode(node);
481+
TreeNode? oldParent = enterParent(node);
482+
_visitAnnotations(node.annotations);
483+
exitParent(oldParent);
484+
exitTreeNode(node);
485+
}
486+
487+
@override
488+
void visitLibraryDependency(LibraryDependency node) {
489+
enterTreeNode(node);
490+
TreeNode? oldParent = enterParent(node);
491+
_visitAnnotations(node.annotations);
492+
visitList(node.combinators, this);
493+
exitParent(oldParent);
494+
exitTreeNode(node);
495+
}
496+
468497
Map<Reference, ExtensionTypeMemberDescriptor> _computeExtensionTypeMembers(
469498
Library library) {
470499
if (_extensionTypeMembers == null) {
@@ -518,7 +547,9 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
518547
_computeExtensionMembers(node.enclosingLibrary);
519548
declareTypeParameters(node.typeParameters);
520549
final TreeNode? oldParent = enterParent(node);
521-
node.visitChildren(this);
550+
_visitAnnotations(node.annotations);
551+
visitList(node.typeParameters, this);
552+
node.onType.accept(this);
522553
exitParent(oldParent);
523554
undeclareTypeParameters(node.typeParameters);
524555
currentExtension = null;
@@ -548,7 +579,10 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
548579
"Found $type.");
549580
}
550581
}
551-
node.visitChildren(this);
582+
_visitAnnotations(node.annotations);
583+
visitList(node.typeParameters, this);
584+
node.declaredRepresentationType.accept(this);
585+
visitList(node.procedures, this);
552586
exitParent(oldParent);
553587
undeclareTypeParameters(node.typeParameters);
554588
currentExtensionTypeDeclaration = null;
@@ -570,7 +604,9 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
570604
currentParent = node;
571605
// Visit children without checking the parent pointer on the typedef itself
572606
// since this can be called from a context other than its true parent.
573-
node.visitChildren(this);
607+
_visitAnnotations(node.annotations);
608+
visitList(node.typeParameters, this);
609+
node.type?.accept(this);
574610
currentParent = savedParent;
575611
typeParametersInScope = savedTypeParameters;
576612
typedefState[node] = TypedefState.Done;
@@ -667,12 +703,27 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
667703
node.initializer?.accept(this);
668704
node.type.accept(this);
669705
classTypeParametersAreInScope = false;
670-
visitList(node.annotations, this);
706+
_visitAnnotations(node.annotations);
671707
exitParent(oldParent);
672708
currentMember = null;
673709
exitTreeNode(node);
674710
}
675711

712+
void _visitAnnotations(List<Expression> annotations) {
713+
for (Expression annotation in annotations) {
714+
if (stage >= VerificationStage.afterConstantEvaluation) {
715+
if (!(annotation is ConstantExpression ||
716+
annotation is InvalidExpression)) {
717+
problem(
718+
annotation,
719+
"Unexpected annotation $annotation (${annotation.runtimeType}). "
720+
"Expected a ConstantExpression or InvalidExpression.");
721+
}
722+
}
723+
annotation.accept(this);
724+
}
725+
}
726+
676727
@override
677728
void visitProcedure(Procedure node) {
678729
enterTreeNode(node);
@@ -742,7 +793,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
742793
}
743794
node.function.accept(this);
744795
classTypeParametersAreInScope = false;
745-
visitList(node.annotations, this);
796+
_visitAnnotations(node.annotations);
746797
exitParent(oldParent);
747798
// TODO(johnniwinther): Enable this invariant. Possibly by removing bodies
748799
// from external procedures declared with a body or by removing the external
@@ -788,7 +839,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
788839
}
789840
exitLocalScope(stackHeight);
790841
classTypeParametersAreInScope = false;
791-
visitList(node.annotations, this);
842+
_visitAnnotations(node.annotations);
792843
exitParent(oldParent);
793844
// TODO(johnniwinther): Enable this invariant. Possibly by removing bodies
794845
// from external constructors declared with a body or by removing the
@@ -815,7 +866,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
815866
declareTypeParameters(node.typeParameters);
816867
TreeNode? oldParent = enterParent(node);
817868
classTypeParametersAreInScope = false;
818-
visitList(node.annotations, this);
869+
_visitAnnotations(node.annotations);
819870
classTypeParametersAreInScope = true;
820871
visitList(node.typeParameters, this);
821872
visitList(node.fields, this);
@@ -1018,7 +1069,10 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
10181069
"VariableDeclaration must be a direct child of a Block, "
10191070
"not ${parent.runtimeType}.");
10201071
}
1021-
visitChildren(node);
1072+
TreeNode? oldParent = enterParent(node);
1073+
_visitAnnotations(node.annotations);
1074+
node.initializer?.accept(this);
1075+
exitParent(oldParent);
10221076
declareVariable(node.variable);
10231077
if (afterConst && node.isConst && constantLocalsShouldBeRemoved) {
10241078
Expression? initializer = node.initializer;

0 commit comments

Comments
 (0)