Repository: fraunhofer-aisec/cpg
Issue: NullPointerException in ScopeManager

I am running the CPG on a large code base and I discovered this NPE. I am trying to isolate the file where it occurs, unfortunately I cannot share the whole code base.

Stracktrace

```
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
	at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
	at com.aybaze.AnalyzeU.AppKt.main(App.kt:37)
Caused by: java.lang.NullPointerException
	at de.fraunhofer.aisec.cpg.passes.scopes.ScopeManager.lambda$leaveScope$7(ScopeManager.java:253)
	at de.fraunhofer.aisec.cpg.passes.scopes.ScopeManager.getFirstScopeThat(ScopeManager.java:275)
	at de.fraunhofer.aisec.cpg.passes.scopes.ScopeManager.getFirstScopeThat(ScopeManager.java:269)
	at de.fraunhofer.aisec.cpg.passes.scopes.ScopeManager.leaveScope(ScopeManager.java:253)
	at de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass.handleDeclaration(EvaluationOrderGraphPass.java:211)
	at de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass.handleDeclaration(EvaluationOrderGraphPass.java:190)
	at de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass.handleDeclaration(EvaluationOrderGraphPass.java:177)
	at de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass.accept(EvaluationOrderGraphPass.java:100)
	at de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass.accept(EvaluationOrderGraphPass.java:59)
	at de.fraunhofer.aisec.cpg.TranslationManager.lambda$analyze$0(TranslationManager.java:104)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1700)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
```


Changed files:
src/main/java/de/fraunhofer/aisec/cpg/passes/scopes/ScopeManager.java

diff --git a/src/main/java/de/fraunhofer/aisec/cpg/passes/scopes/ScopeManager.java b/src/main/java/de/fraunhofer/aisec/cpg/passes/scopes/ScopeManager.java
index c1c6ba86a..e1b988fb1 100644
--- a/src/main/java/de/fraunhofer/aisec/cpg/passes/scopes/ScopeManager.java
+++ b/src/main/java/de/fraunhofer/aisec/cpg/passes/scopes/ScopeManager.java
@@ -250,7 +250,14 @@ public class ScopeManager {
    */
   @Nullable
   public Scope leaveScope(Node nodeToLeave) {
-    Scope leaveScope = getFirstScopeThat(scope -> scope.astNode.equals(nodeToLeave));
+    // Check to return as soon as we know that there is no associated scope, this check could be
+    // omitted
+    // but will increase runtime if leaving a node without scope will happen often.
+    if (!scopeMap.containsKey(nodeToLeave)) {
+      return null;
+    }
+    Scope leaveScope =
+        getFirstScopeThat(scope -> scope.astNode != null && scope.astNode.equals(nodeToLeave));
     if (leaveScope == null) {
       if (scopeMap.containsKey(nodeToLeave)) {
         LOGGER.error(