From 020f2b52b4a314f1aa560494d39b2a064706bca8 Mon Sep 17 00:00:00 2001 From: Ben Barham Date: Wed, 30 Aug 2023 21:03:03 -0700 Subject: [PATCH] [Completion] ~ExpectedTypeContext must be called after ~CCResultBuilder There's a subtle stack UAF here - `~CodeCompletionResultBuilder` would be called *after* `~ExpectedTypeContext` as `ExpectedTypeContext` was defined after `CodeCompletionResultBuilder`. Fix the order they're created to prevent this. --- lib/IDE/CodeCompletion.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 796a335e38533..a0aba04d859ea 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -896,14 +896,19 @@ static void addKeywordsAfterReturn(CodeCompletionResultSink &Sink, DeclContext * // using the solver-based implementation. Add the result manually. if (auto ctor = dyn_cast_or_null(DC->getAsDecl())) { if (ctor->isFailable()) { + Type resultType = ctor->getResultInterfaceType(); + + // Note that `TypeContext` must stay alive for the duration of + // `~CodeCodeCompletionResultBuilder()`. + ExpectedTypeContext TypeContext; + TypeContext.setPossibleTypes({resultType}); + CodeCompletionResultBuilder Builder(Sink, CodeCompletionResultKind::Literal, SemanticContextKind::None); Builder.setLiteralKind(CodeCompletionLiteralKind::NilLiteral); Builder.addKeyword("nil"); - Builder.addTypeAnnotation(ctor->getResultInterfaceType(), {}); - Builder.setResultTypes(ctor->getResultInterfaceType()); - ExpectedTypeContext TypeContext; - TypeContext.setPossibleTypes({ctor->getResultInterfaceType()}); + Builder.addTypeAnnotation(resultType, {}); + Builder.setResultTypes(resultType); Builder.setTypeContext(TypeContext, DC); } }