public class GlobalDataSqli {

    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS", "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur SQLI
    // functions deprecated: mysql_db_query, mysqli_execute, mysqli_master_query
    private final static String TaintFunctions[] = {"mysql_db_query", "mysql_query", "mysql_unbuffered_query", "mysqli_multi_query", "mysqli_stmt_execute",
                               "mysqli_execute", "mysqli_query", "mysqli_real_query", "mysqli_master_query", "query", "multi_query", "real_query", "execute",
                               "db2_exec", "pg_query", "pg_send_query"};
    /* "mysqli_stmt_execute", "execute" */
    public static List<String> SQLIFunctions = Arrays.asList(TaintFunctions);

    // functions that make secure the user input
    // functions deprecated: mysqli_bind_param, mysql_escape_string, mysqli_escape_string
    private final static String SecureFunctions[] = {"mysql_escape_string", "mysql_real_escape_string", "mysqli_escape_string", "mysqli_real_escape_string",
                                "mysqli_stmt_bind_param", "escape_string", "real_escape_string", "bind_param",
                                "db2_escape_string", "pg_escape_string", "pg_escape_bytea", "pg_escape_literal", "san_sqli"};
    //private final static String SecureFunctions[] = {};    
    public static List<String> SQLSecFunctions = Arrays.asList(SecureFunctions);

    // functions to connect to db
    private final static String ConnectFunctions[] = {"mysql_connect", "mysql_pconnect", "mysqli_connect", "mysqli_real_connect", "real_connect", "__construct",
                                "db2_connect", "db2_pconnect", "pg_connect", "pg_pconnect"};
    public static List<String> SQLConnectFunctions = Arrays.asList(ConnectFunctions);

    // functions to select db
    private final static String SelectDbFunctions[] = {"mysql_select_db", "mysqli_select_db", "select_db"};
    public static List<String> SQLSelectDbFunctions = Arrays.asList(SelectDbFunctions);
    
    // Mysql keywords
    private final static String clausules[] = {"SELECT", "INSERT INTO", "UPDATE", "ALTER TABLE", "DELETE FROM", "CREATE TABLE", "DROP TABLE",
                                "CREATE DATABASE", "DROP DATABASE", "FROM", "WHERE", "ORDER BY", "GROUP BY", "HAVING"};
    public static List<String> SQLKeywords = Arrays.asList(clausules);    

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static VulnerSQLI currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();

    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataSqli.UserInput){
                if (f.contains(aux) == true){
                    return aux;
                }
        }
        return found;
    }
  
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataSqli.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataSqli.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }     
    
    
    
} public class buildWalkerTree_sqli {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_sqli(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException, RecognitionException {
        try {           
            // Navegate into AST by walker tree
            Sqli def = new Sqli(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            Sqli.prog_return prog = def.prog(); 
        } catch (RecognitionException ex) {
            Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class TaintedTable implements ScopeTainted{
    String nameFile;
    String functionNameCall = "";
    Map<String, RootTaintedSymbol> symbolsRootTainted;

    
    /* CONSTRUCTOR */
    public TaintedTable(String filename) {
     symbolsRootTainted = new LinkedHashMap<String, RootTaintedSymbol>();
     this.nameFile = filename;
    }
    
    // Constructor to user function and class method tainted table
    public TaintedTable(String functionName, String filename) {
     symbolsRootTainted = new LinkedHashMap<String, RootTaintedSymbol>();
     this.nameFile = filename;
     this.functionNameCall = functionName;
    }

    /* METHODS that satisfy TaintedScope interface*/

    /*
     * Give the the name of taintedScope. How this scope don't have parent, then
     * your name is "globaltainted"
     */
    public String getScopeTaintedName() {
        return nameFile;
    }
    
    /*
     * Give the the name of user function or class method.
     */
    public String getFunctionNameCall() {
        return functionNameCall;
    }    

    /*
     * If the tainted scope is enclosing in another (if have parent), give the
     * name of the parent scope.
     * How the Tainted Table is the main scope, then don't have parent (null)
     */
    public ScopeTainted getEnclosingScopeTainted() {
    	return null;
    }

    /*
     * Give the main Map that contain the tainted variables
     */
    public Map getTaintedMembers() {
        return symbolsRootTainted;
    }

    /*
     * Insert a tainted variable in main Map.
     * Each member of main Map is a RelatedTaintedSymbol, composed by:
     * Map VariableTaintedSymbol and List to store code lines of tainted variables
     */
    public void define(RootTaintedSymbol rts) {
    	symbolsRootTainted.put(rts.getScopeTaintedName(), rts);
    }

    /*
     * Give RelatedTaintedSymbol from main Map, search by a gived name
     */
    public RootTaintedSymbol resolve(String name) {
    	return symbolsRootTainted.get(name);
    }

    public TaintedTable copyTaintedTable() {
        TaintedTable tab = new TaintedTable("aux");
        for(Iterator <Symbol> it = this.getTaintedMembers().values().iterator(); it.hasNext();){
		Symbol cs = it.next();
            try {
                tab.getTaintedMembers().put(cs.getName(), cs.clone());
            } catch (CloneNotSupportedException ex) {
                Logger.getLogger(TaintedTable.class.getName()).log(Level.SEVERE, null, ex);
            }
	 }
    	return tab;
        
    }
    
    public void copyToMTS(TaintedTable m, UntaintedTable mu) { // m = mts
        Iterator <RootTaintedSymbol> it = this.getTaintedMembers().values().iterator(); // mts_aux
        RootTaintedSymbol rts, rts_m;
        RelatedTaintedSymbol rtt=null, rtt_m=null;
        VariableTaintedSymbol vts = null, vts_m;
        for(;it.hasNext();){//mts_aux
            rts = it.next();
            if (m.getTaintedMembers().containsKey(rts.getScopeTaintedName()) == false)
                m.getTaintedMembers().put(rts.getScopeTaintedName(), rts);
            else{
                rts_m = (RootTaintedSymbol) m.getTaintedMembers().get(rts.getScopeTaintedName());
                Iterator <Integer> it1;
                Iterator <String> it2 = rts.getFilesList().iterator();
                int i;
                String s;
                for (it1 = rts.getLinesList().iterator(); it1.hasNext();){
                    i = it1.next();
                    s = it2.next();
                    if (i != 0){ // as var globais em mts_aux tem linha = 0
                        if (rts_m.getLinesList().contains(i) == false ||
                            rts_m.getLinesList().contains(i) == true && rts_m.getFilesList().contains(s) == false){
                            rts_m.getLinesList().add(i);
                            rts_m.getFilesList().add(s);
                            for (Iterator <RelatedTaintedSymbol> it3 = rts.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt = it3.next();
                                if (rtt.getLineRts() == i && rtt.getFileRts().equals(s)){
                                    rts_m.define(rtt);
                                    break;
                                }
                            }
                        }
                        else{
                            // Obter RelatedTaintedSymbol de mts_princ de i e s
                            for (Iterator <RelatedTaintedSymbol> it3 = rts_m.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt_m = it3.next();
                                if (rtt_m.getLineRts() == i && rtt_m.getFileRts().equals(s))
                                    break;
                            }
                            // Obter RelatedTaintedSymbol de mts_aux de i e s para copiar os vts para mts_princ
                            for (Iterator <RelatedTaintedSymbol> it3 = rts.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt = it3.next();
                                if (rtt.getLineRts() == i && rtt.getFileRts().equals(s))
                                    break;
                            }
                            
                            Iterator <VariableTaintedSymbol> it3 = rtt.getTaintedMembers().values().iterator();
                            for (;it3.hasNext();){
                                vts = it3.next();
                                if (rtt_m.getTaintedMembers().containsKey(vts.getName()) == false){
                                    rtt_m.define(vts);
                                }
                                else{
                                    vts_m = (VariableTaintedSymbol) rtt_m.getTaintedMembers().get(vts.getName());
                                    Iterator <Integer> it4 = vts.getVariableLines().iterator();
                                    Iterator <String> it5 = vts.getVariableFiles().iterator();
                                    for (; it4.hasNext();){
                                        int ii = it4.next();
                                        String ss = it5.next();
                                        if (vts_m.getVariableLines().contains(ii) == false ||
                                            vts_m.getVariableLines().contains(ii) == true && vts_m.getVariableFiles().contains(ss) == false){
                                            vts_m.getVariableLines().add(ii);
                                            vts_m.getVariableFiles().add(ss);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                // Se rts passou de untainted (vindo de mus) para tainted (em mts_aux), retirar rts de mus
                Symbol sym = rts.getSymbol();
                if (mu.existSymbol(sym.getName()) == true) // verify if symbol pass to untaint to taint
                    mu.removeUntaintSymbol(sym);
            }
        }
    }
    
    public void copyGlobalsToMTS(TaintedTable mts_princ , UntaintedTable mus_princ , UntaintedTable mus_aux, MethodSymbol meth_sym_clone){
        for(Iterator <Symbol> it = meth_sym_clone.getGlobalVarsOfFunction().values().iterator(); it.hasNext();){
            Symbol sym = it.next();
            if (this.getTaintedMembers().containsKey(sym.getName()) == true && mus_aux.existSymbol(sym.getName()) == false){
                if (mts_princ.getTaintedMembers().containsKey(sym.getName()) == true){
                    // Se passou de untainted para tainted, retirar de untainted
                    if(mus_princ.existSymbol(sym.getName()) == true)
                        mus_princ.removeUntaintSymbol(sym);                   
                else{
                    RootTaintedSymbol rts_aux = (RootTaintedSymbol) this.getTaintedMembers().get(sym.getName());
                    RootTaintedSymbol rts_princ = (RootTaintedSymbol) mts_princ.getTaintedMembers().get(sym.getName());
                    int index = rts_aux.getLinesList().size()-1;
                    int i = (Integer) rts_aux.getLinesList().get(index);
                    String s = (String) rts_aux.getFilesList().get(index);
                    RelatedTaintedSymbol rtt_aux = (RelatedTaintedSymbol) rts_aux.getListTaintedMembers().get(index);
                    if (rts_princ.getLinesList().contains(i) == false){
                        rts_princ.getLinesList().add(i);
                        rts_princ.getFilesList().add(s);
                        rts_princ.getListTaintedMembers().add(rtt_aux);
                    }
                    else{
                        int index_princ = rts_princ.getLinesList().indexOf(i);
                        if (rts_princ.getFilesList().get(index_princ).equals(s) == false){
                            rts_princ.getLinesList().add(i);
                            rts_princ.getFilesList().add(s);
                            rts_princ.getListTaintedMembers().add(rtt_aux);
                        }
                        else{
                            rts_princ.getListTaintedMembers().set(index_princ, rtt_aux);
                        }
                    }
                }
                }
            }
        }
    }

public void removeDuplicates(Symbol sym){
    if (this.getTaintedMembers().containsKey(sym.getScope().getScopeName()) == true){
        RootTaintedSymbol Rrt = (RootTaintedSymbol) this.getTaintedMembers().get(sym.getScope().getScopeName());
        if (Rrt.getLinesList().size() > 1){
            int last_i = (Integer) Rrt.getLinesList().get(Rrt.getLinesList().size()-1);
            String last_s = (String) Rrt.getFilesList().get(Rrt.getFilesList().size()-1);
            
            int penultimate_i = (Integer) Rrt.getLinesList().get(Rrt.getLinesList().size()-2);
            String penultimate_s = (String) Rrt.getFilesList().get(Rrt.getFilesList().size()-2);
            if (last_i == penultimate_i && last_s.equals(penultimate_s) == true){
                Rrt.getLinesList().remove(Rrt.getLinesList().size()-1);
                Rrt.getFilesList().remove(Rrt.getFilesList().size()-1);
            }
        }
     }
}    
    
    
    public void printMTS(){
        TaintedTable mts = this;
        Iterator <RootTaintedSymbol> it = mts.getTaintedMembers().values().iterator();
        System.out.println("\n\nTainted File = "+mts.getScopeTaintedName()+"\n");
        System.out.println("Nº de Vars/funcoes tainted = "+mts.getTaintedMembers().size()+"\n");
        System.out.println("Mapa de Vars/funcoes tainted e suas dependencias:\n");
        System.out.println("**************************************************\n");
        VariableTaintedSymbol aux1;
        RelatedTaintedSymbol aux;
        RootTaintedSymbol raux;
        for(; it.hasNext();){
            raux = it.next();
            System.out.println("\nROOT_VAR: "+raux.getName());
            for(Iterator <RelatedTaintedSymbol> it2 = raux.getListTaintedMembers().iterator(); it2.hasNext();){
                aux = it2.next();
                System.out.println("\tLine: "+aux.getLineRts()+"  FILE: "+aux.getFileRts());
                Iterator <VariableTaintedSymbol> it3 = aux.getTaintedMembers().values().iterator();
                for(;it3.hasNext(); ){
                    aux1 = it3.next();
                    System.out.println("\t\tName: "+aux1.getName()+"  Lines: "+aux1.getVariableLines().toString()+
                                       "  FILES: "+aux1.getVariableFiles().toString());
                }
            }
        }
    }    
    
    
    public void cleanAll(){
        Collection <RootTaintedSymbol> c = symbolsRootTainted.values();
    	c.removeAll(c);
    	symbolsRootTainted.clear();
    }
    
    @Override
    public String toString() {
    	return getScopeTaintedName()+":"+symbolsRootTainted;
    }

    public void define(Symbol sym) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List getListTaintedMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

} public class UntaintedTable {
    Map<String, Symbol> symbolsUntainted;

    /* CONSTRUCTOR */
    public UntaintedTable() {
     symbolsUntainted = new LinkedHashMap<String, Symbol>();
    }


    /* METHODS of the class*/

    /*
     * Give the Map that contain the untainted variables
     */
    public Map getUntaintedMembers() {
        return symbolsUntainted;
    }

    /*
     * Verify if a untainted variable exist in Map
     */
    public Boolean existSymbol(String s) {
        return symbolsUntainted.containsKey(s);
    }

    /*
     * Insert a untainted variable in Map
     */
    public void insertUntaintSymbol(Symbol sym) {
    	symbolsUntainted.put(sym.getName(), sym);
    }

    /*
     * Remove a untainted variable from Map
     */
    public void removeUntaintSymbol(Symbol sym) {
    	symbolsUntainted.remove(sym.getName());
    }

    public void copyToMUS(UntaintedTable m) { // m = mus
        Iterator <Symbol> it = this.getUntaintedMembers().values().iterator(); // mus_aux
        Symbol sym;
        for(;it.hasNext();){
            sym = it.next();
            if (!sym.getName().equals("return"))
                m.getUntaintedMembers().put(sym.getName(), sym);
        }
    }

    public void copyGlobalsToMUS(TaintedTable mts_princ , UntaintedTable mus_princ, MethodSymbol meth_sym_clone){
        for(Iterator <Symbol> it = meth_sym_clone.getGlobalVarsOfFunction().values().iterator(); it.hasNext();){
            Symbol sym = it.next();
            if (this.getUntaintedMembers().containsKey(sym.getName()) == true && mts_princ.getTaintedMembers().containsKey(sym.getName()) == true) {
                if (mus_princ.existSymbol(sym.getName()) == false){
                    // Se passou de tainted para untainted, colocar em untainted
                    mus_princ.insertUntaintSymbol(sym);
                }
            }
        }
    }    
    
    
    public UntaintedTable copyUntaintedTable() {
        UntaintedTable tab = new UntaintedTable();
        for(Iterator <Symbol> it = this.getUntaintedMembers().values().iterator(); it.hasNext();){
		Symbol cs = it.next();
            try {
                tab.getUntaintedMembers().put(cs.getName(), cs.clone());
            } catch (CloneNotSupportedException ex) {
                Logger.getLogger(UntaintedTable.class.getName()).log(Level.SEVERE, null, ex);
            }
	 }
    	return tab;
    }
    
     public void cleanAll(){
        Collection <Symbol> c = this.symbolsUntainted.values();
    	c.removeAll(c);
    	this.symbolsUntainted.clear();
    }

} public class GlobalDataCodeInj {
    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS", "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS", "_FILES"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur RFI/LFI/DT
    // readfile can occur Source-code disclosure, too
    private final static String RFITaintFunctions[] = {"readfile", "highlight_file", "fopen", "file_get_contents", "file", "copy", 
    "unlink", "move_uploaded_file", "imagecreatefromgd2", "imagecreatefromgd2part", "imagecreatefromgd",
    "imagecreatefromgif", "imagecreatefromjpeg", "imagecreatefrompng", "imagecreatefromstring", "imagecreatefromwbmp",
    "imagecreatefromxbm", "imagecreatefromxpm", "require", "require_once", "include", "include_once"};
    public static List<String> RFIFunctions = Arrays.asList(RFITaintFunctions);
     
    // functions where can occur OS command injection
    private final static String OSTaintFunctions[] = {"passthru", "system", "shell_exec", "exec", "pcntl_exec", 
    "popen", "proc_open"};
    public static List<String> OSFunctions = Arrays.asList(OSTaintFunctions);

    // functions where can occur Eval-injection
    private final static String EvalTaintFunctions[] = {"eval", "preg_replace"};
    public static List<String> EvalFunctions = Arrays.asList(EvalTaintFunctions);

    // WAP sanitizations functions - fixes
    private final static String FixesFunctions[] = {"san_mix", "san_osci", "san_eval"};
    public static List<String> CInjSecFunctions = Arrays.asList(FixesFunctions);    
    
    

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static Vulner currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();
    
    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataCodeInj.UserInput){
                if (f.contains(aux) == true){
                    return aux;
                }
        }
        return found;
    }
    
    public static String getTypeVulInjection(String function){
        if (function.equals("readfile") == true || function.equals("highlight_file") == true)
            return "Source Code Discloser";
        else
            if (function.equals("eval") == true || function.equals("preg_replace") == true)
                return "PHP Code Injection";
            else
                if (GlobalDataCodeInj.OSFunctions.contains(function))
                    return "OS Command Injection";
                else
                    return "RFI, LFI, DT";
    }
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }    
} public class buildWalkerTree_CodeInj {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_CodeInj(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException {
        try {
            // Navegate into AST by walker tree
            CodeInjection def = new CodeInjection(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            CodeInjection.prog_return prog = def.prog();
        } catch (RecognitionException ex) {
            Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class GlobalDataXSS {
    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS",
                                                "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS", "_FILES", "_SERVER"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur XSS Reflected and Stored
    private final static String XSSTaintFunctions[] = {"echo", "print", "printf", "file_get_contents", "file_put_contents",
                                                        "fprintf", "fgets", "fgetc", "fscanf", "die", "exit", "error"};
    public static List<String> XSSFunctions = Arrays.asList(XSSTaintFunctions);
   
    // functions that make secure the user input
    //private final static String SecureFunctions[] = {"htmlentities", "htmlspecialchars", "strip_tags", "urlencode",
    //                                                  "san_out", "san_rdata", "san_wdata"};
    private final static String SecureFunctions[] = {};    
    public static List<String> XSSSecFunctions = Arrays.asList(SecureFunctions);

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static VulnerXSS currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();
    
    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataXSS.UserInput){
                if (f.contains(aux) == true){
                    //found = aux;
                    return aux;
                }
        }
        return found;
    }
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataXSS.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataXSS.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }     
} public class buildWalkerTree_XSS {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_XSS(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException {
        try {
            // Navegate into AST by walker tree
            XSS def = new XSS(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            XSS.prog_return prog = def.prog();
        } catch (RecognitionException ex) {
           Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class MethodTaintedTable implements ScopeTainted{
    String filename;
    List <MethodSymbolTainted> methodsTainteds;
    
    /* CONSTRUCTOR */
    public MethodTaintedTable (String f){
        this.filename = f;
        methodsTainteds = new ArrayList<MethodSymbolTainted>();
    }

    public String getScopeTaintedName() {
        return this.filename;
    }

    public List getListTaintedMembers() {
        return this.methodsTainteds;
    }    
    
    public ScopeTainted getEnclosingScopeTainted() {
        return null;
    }

    public void define(MethodSymbolTainted mss) {
        this.methodsTainteds.add(mss);
    }

    public void define(Symbol sym) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    public Map getTaintedMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }    
} public class GlobalDataApp {
    /**
     * args Flags
     * index 0: presence of -a
     *          analysis without automatic correction
     * index 1: presence of -p
     *          analysis of a project
     * index 2: presence of files
     *          analysis of one or more php files
     * index 3: presence of -sqli
     *          SQLI analysis
     * index 4: presence of -out
     *          stdout forward to output file
     * index 5: presence of -s
     *          show only global summary
     * index 6: presence of -ci
     *          RFI/LFI/DT SCD, OS, Eval analysis 
     * index 7: presence of -xss
     *          XSS Reflected, Store and DOM??
     * index 8: presence of --dbms <dbms>
     *          select DBMS: db2, PostgreSQL, MySQL. If not specify any, MySQL is selected
     *          -dbms mysql; -dbms bd2; -dbms pg
     * index 9: presence of -all
     *          presence of all types of detection
     */
    public static int args_flags[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    public static int numAnalysis = 0;
    public static String dbms = "mysql";
    public static Classifier cf_lr;
    public static Classifier cf_rt;
    public static Classifier cf_svm;
    public static Classifier cf_jrip;
    public static JRip jrip;
    public static Boolean isWindows = false;

    /*
     * Load dataset and build classifier to data mining
     */
    public static Classifier loadClassifier(String nameClassifier) throws IOException{      
        Classifier javaml = null;
        
        /* Load the data set */
        // VERSAO FINAL
        Dataset data;
        if (nameClassifier.equals("svm") == true)
            data = FileHandler.loadDataset(new File("data" + File.separator + "dataset_balanced.data"), 15, ",");
        else
            data = FileHandler.loadDataset(new File("data" + File.separator + "dataset.data"), 15, ",");
        
        
        //Dataset data = FileHandler.loadDataset(new File(".." + File.separator + "data" + File.separator + "dataset.data"), 15, ",");
               
        // Create Weka classifier
        if (nameClassifier.equals("lr") == true){
            Logistic lr = new weka.classifiers.functions.Logistic();
            lr.setDebug(false);
            lr.setMaxIts(-1);
            lr.setRidge(1.0E-8);

            // Wrap Weka classifier in bridge 
            Classifier javaml_lr = new WekaClassifier(lr);
            
            // Build the classifier         
            javaml_lr.buildClassifier(data);
            javaml = javaml_lr;
        }
        
        // Create Weka classifier
        if (nameClassifier.equals("rt") == true){
            RandomTree rt = new weka.classifiers.trees.RandomTree();
            rt.setKValue(0);
            rt.setDebug(false);
            rt.setMaxDepth(0);
            rt.setMinNum(1.0);
            rt.setSeed(1);
            
            // Wrap Weka classifier in bridge 
            Classifier javaml_rt = new WekaClassifier(rt);
            
            // Build the classifier         
            javaml_rt.buildClassifier(data);
            javaml = javaml_rt;
        }
        
        // Create Weka classifier
        if (nameClassifier.equals("jrip") == true){
            jrip = new weka.classifiers.rules.JRip();
            jrip.setCheckErrorRate(true);
            jrip.setDebug(false);
            jrip.setFolds(3);
            jrip.setMinNo(2.0);
            jrip.setOptimizations(2);
            jrip.setSeed(1);
            jrip.setUsePruning(true);
            
          
            // Wrap Weka classifier in bridge 
            Classifier javaml_jrip = new WekaClassifier(jrip);
            
            // Build the classifier         
            javaml_jrip.buildClassifier(data);
            javaml = javaml_jrip;
        }        

        // Create Weka classifier
        if (nameClassifier.equals("svm") == true){
            // SMOTE filter applied to dataset
            /*
            SMOTE smote = new weka.filters.supervised.instance.SMOTE();
            smote.setClassValue("Yes");
            smote.setNearestNeighbors(5);
            smote.setPercentage(100.0);
            smote.setRandomSeed(1);
            */
            
            //kernel
            PolyKernel kernel = new weka.classifiers.functions.supportVector.PolyKernel();
            kernel.setCacheSize(250007);
            kernel.setExponent(1.0);           
            
            SMO svm = new weka.classifiers.functions.SMO();
            svm.setBuildLogisticModels(false);
            svm.setC(1.0);
            svm.setChecksTurnedOff(false);
            svm.setDebug(false);
            svm.setEpsilon(1.0E-12);
            svm.setNumFolds(-1);
            svm.setRandomSeed(1);
            svm.setToleranceParameter(0.001);
            //svm.setFilterType(0);
            svm.setKernel(kernel);
            
            // Wrap Weka classifier in bridge 
            Classifier javaml_svm = new WekaClassifier(svm);
            
            // Build the classifier         
            javaml_svm.buildClassifier(data);
            javaml = javaml_svm;
        } 
        
        return javaml;
    }
} public class buildAST {
    private CommonTreeNodeStream nodes = null;
    private Boolean validFile = false;
    private String finalFile;
    
    
    // *** CONSTRUCTORS
//    public buildAST(String filename, SymbolTable st, List files, int fileVerified) throws IOException{
    public buildAST(String filename, int fileVerified) throws IOException {
        String final_file;
        Boolean encontrei = false;
        Boolean valid_file = false;

        if (fileVerified == 0){ // somente para ficheiros de include/require
            ManageFiles ff = new ManageFiles(filename);
            final_file = ff.composePathFile(filename, ff.getBaseDir());
            ManageFiles fff = new ManageFiles(final_file);
            if (fff.existFile(final_file)){
                encontrei = true;
                valid_file = true;
            }           
        }
        else {// if (verified == 1)
            final_file = filename;
            valid_file = true;
            this.validFile = true;
            this.finalFile = final_file;
        }

        if (valid_file == true){
        try {
            InputStream is = new FileInputStream(final_file);
       
            // Create input stream from standard input
            ANTLRInputStream input = new ANTLRInputStream(is);
            // Create a lexer attached to that input stream
            PhpLexer lexer = new PhpLexer(input);
            // Create a stream of tokens pulled from the lexer
            CommonTokenStream tokens = new CommonTokenStream(lexer);

            // Create a parser attached to the token stream
            PhpParser parser = new PhpParser(tokens);
            RuleReturnScope r = parser.compilationUnit();   // launch parser

            // Get AST from result of parser
            CommonTree t = (CommonTree)r.getTree();
            //CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
            this.nodes = new CommonTreeNodeStream(t);
            nodes.setTokenStream(tokens);
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + final_file);
        } catch (Exception e) {
            System.err.println("Error parsing " + final_file);
            System.err.println(e.getMessage());
        }
        }

    }
    
    public CommonTreeNodeStream getNodes(){
        return this.nodes;
    }
    
    public Boolean getValidFile(){
        return this.validFile;
    }
    
    public String getFinalFile(){
        return this.finalFile;
    }

}
import org.homeunix.wap.sqli.GlobalDataSqli;
import org.homeunix.wap.sqli.buildWalkerTree_sqli;
import java.io.IOException;
import org.homeunix.wap.table.tainted.TaintedTable;
import org.homeunix.wap.table.tainted.UntaintedTable;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.homeunix.wap.CodeInjection.GlobalDataCodeInj;
import org.homeunix.wap.CodeInjection.buildWalkerTree_CodeInj;
import org.homeunix.wap.XSS.GlobalDataXSS;
import org.homeunix.wap.XSS.buildWalkerTree_XSS;
import org.homeunix.wap.table.tainted.MethodTaintedTable;
import org.homeunix.wap.utils.GlobalDataApp;
import org.homeunix.wap.utils.buildAST;
            if (instTab.containsInstance(s) == true){
                instName = s;
                found = true;
            }
            else{
                if (this.getAliases().containsKey(s)){
                    Symbol sym = (Symbol) this.getAliases().get(s);
                    s = sym.getName();
                }
            }
        }
        return instName;
    }

    /*
     * Return a specific symbol
     */
    public Symbol getSymbolOfListSymbols(String symName){
        Symbol sym_final = null;
        Iterator <Symbol> it = this.getMembers().iterator();
        Symbol sym;
        for (;it.hasNext();){
                sym = it.next();
                if (sym.getName().equals(symName) == true){
                    sym_final = sym;
                    break;
                }
        }
        return sym_final;
    }

    /*
     * Tells if the symbols list contains a gived symbol
     */
    public Boolean containsSymbol(String symName){
        Iterator <Symbol> it = this.getMembers().iterator();
        Symbol sym;
        Boolean haveSymbol = false;
        for (;it.hasNext();){
                sym = it.next();
                if (sym.getName().equals(symName) == true){
                    haveSymbol = true;
                    break;
                }
        }
        return haveSymbol;
    }

    /*
     * Insert a root symbol (new scope) in main Map.
     */
    public void define(Symbol sym, Scope scp, Boolean IsVariableSymbol) {
        symbols.add(sym);
        sym.setRootScope(scp);
        sym.setScope(this);
        sym.setIsVariableSymbol(IsVariableSymbol);
    }

    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setHaveFunctions(){
        haveFunctions = true;
    }

    /*
     * Set true if the analysed file have classes defined by user
     */
    public void setHaveClasses(){
        haveClasses = true;
    }
    
    public void setGlobalVarSymbolTable(String varName, Symbol gvar) {
        globalVars.put(varName, gvar);
    }

    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setAllSymbols(List<Symbol> syms){
        symbols.addAll(syms);
    }
    
    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setAllIncludeFiles(List<String> incs){
        includeFiles.addAll(incs);
    }    

    /*
     * Not relevant here!
     */
    //public Boolean resolve(String name, TaintedTable mts, UntaintedTable mus) {
    public void resolveSymbol(Scope scp, Symbol sy, TaintedTable mts, UntaintedTable mus, String file){
    	//return symbols.get(name);
    //    return true;
    }


    public Boolean resolve(Symbol symb, TaintedTable mts, UntaintedTable mus) {
        return true;
    }
     
    /*
     * Move include file symbolTable from mst to mift
     */
    public void mvIncludeFiles(List fileList) throws IOException{
        for(Iterator <String> it1 = this.getIncludeFiles().iterator(); it1.hasNext();){
            String s = it1.next();
            if(GlobalDataApp.args_flags[3] == 1){
                if (GlobalDataSqli.MainSymbolTable.containsKey(s) == true){
                    GlobalDataSqli.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataSqli.MainSymbolTable.get(s));
                    GlobalDataSqli.MainSymbolTable.remove(s);
                }
                else{
                    if (GlobalDataSqli.MainIncludeFilesTable.containsKey(s) == false){
                        try {
                            // file include do not exists in mst and mift
                            // Create AST
                            buildAST ast = new buildAST(s, 0);