All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.joern.fuzzyc2cpg.parser.functions.builder.ShadowStack Maven / Gradle / Ivy

There is a newer version: 1.1.911
Show newest version
package io.joern.fuzzyc2cpg.parser.functions.builder;

import io.joern.fuzzyc2cpg.ast.AstNode;
import io.joern.fuzzyc2cpg.ast.langc.statements.blockstarters.IfStatement;
import io.joern.fuzzyc2cpg.ast.logical.statements.CompoundStatement;
import io.joern.fuzzyc2cpg.ast.statements.blockstarters.DoStatement;
import io.joern.fuzzyc2cpg.ast.statements.blockstarters.TryStatement;
import java.util.EmptyStackException;
import java.util.Stack;

public class ShadowStack {

  private Stack stack = new Stack<>();
  private Stack itemStack;

  public ShadowStack(Stack aItemStack) {
    itemStack = aItemStack;
  }

  public void push(AstNode statementItem) {
    if (statementItem instanceof IfStatement
        || statementItem instanceof DoStatement
        || statementItem instanceof TryStatement) {
      AstNode parentCompound = parentCompoundFromItemStack(itemStack);

      stack.push(new StackItem(statementItem, parentCompound));
    }
  }

  public void pop() {
    AstNode topOfItemStack = itemStack.peek();

    while (stack.size() > 0
        && stack.peek().parentCompound == topOfItemStack) {
      stack.pop();
    }
  }

  public IfStatement getIfInElseCase() {
    if (stack.size() < 2) {
      return null;
    }

    StackItem topItem = stack.pop();
    StackItem returnItem = stack.pop();
    stack.push(topItem);
    return (IfStatement) returnItem.ifOrDoOrTry;
  }

  public IfStatement getIf() {
    IfStatement retval;
    StackItem item = null;

    try {
      item = stack.pop();
      retval = (IfStatement) item.ifOrDoOrTry;
    } catch (EmptyStackException ex) {
      return null;
    } catch (ClassCastException ex) {
      stack.push(item);
      return null;
    }

    return retval;
  }

  public DoStatement getDo() {
    DoStatement retval;
    StackItem item = null;

    try {
      item = stack.pop();
      retval = (DoStatement) item.ifOrDoOrTry;

      if (itemStack.contains(retval)) {
        stack.push(item);
        return null;
      }

    } catch (EmptyStackException ex) {
      return null;
    } catch (ClassCastException ex) {
      stack.push(item);
      return null;
    }

    return retval;
  }

  private AstNode parentCompoundFromItemStack(Stack itemStack) {
    // Watchout: we are assuming that this function is never
    // called when 0 compound statements are on the stack.
    // If this ever happens, null is returned.

    AstNode parentCompound = null;
    // walk stack from top to bottom
    for (int i = itemStack.size() - 1; i >= 0; i--) {
      if (itemStack.get(i) instanceof CompoundStatement) {
        parentCompound = itemStack.get(i);
        break;
      }
    }
    return parentCompound;
  }

  public TryStatement getTry() {
    TryStatement retval;
    StackItem item = null;

    try {
      // keep try statement on stack for further catch expressions
      item = stack.peek();
      retval = (TryStatement) item.ifOrDoOrTry;

      if (itemStack.contains(retval)) {
        stack.push(item);
        return null;
      }

    } catch (EmptyStackException ex) {
      return null;
    } catch (ClassCastException ex) {
      stack.push(item);
      return null;
    }

    return retval;
  }

  private static class StackItem {

    public AstNode parentCompound;
    public AstNode ifOrDoOrTry;

    public StackItem(AstNode item, AstNode parent) {
      ifOrDoOrTry = item;
      parentCompound = parent;
    }

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy