Search in sources :

Example 11 with BInvokableSymbol

use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol in project ballerina by ballerina-lang.

the class TaintAnalyzer method analyzeInvocation.

// Private methods relevant to invocation analysis.
private void analyzeInvocation(BLangInvocation invocationExpr) {
    BInvokableSymbol invokableSymbol = (BInvokableSymbol) invocationExpr.symbol;
    Map<Integer, TaintRecord> taintTable = invokableSymbol.taintTable;
    List<Boolean> returnTaintedStatus = new ArrayList<>();
    TaintRecord allParamsUntaintedRecord = taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX);
    if (allParamsUntaintedRecord.taintError != null && allParamsUntaintedRecord.taintError.size() > 0) {
        // This can occur when there is a error regardless of tainted status of parameters.
        // Example: Tainted value returned by function is passed to another functions's sensitive parameter.
        addTaintError(allParamsUntaintedRecord.taintError);
    } else {
        returnTaintedStatus = new ArrayList<>(taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX).retParamTaintedStatus);
    }
    if (invocationExpr.argExprs != null) {
        for (int argIndex = 0; argIndex < invocationExpr.argExprs.size(); argIndex++) {
            BLangExpression argExpr = invocationExpr.argExprs.get(argIndex);
            argExpr.accept(this);
            // return-tainted-status when the given argument is in tainted state.
            if (getObservedTaintedStatus()) {
                TaintRecord taintRecord = taintTable.get(argIndex);
                if (taintRecord == null) {
                    // This is when current parameter is "sensitive". Therefore, providing a tainted
                    // value to a sensitive parameter is invalid and should return a compiler error.
                    int requiredParamCount = invokableSymbol.params.size();
                    int defaultableParamCount = invokableSymbol.defaultableParams.size();
                    int totalParamCount = requiredParamCount + defaultableParamCount + (invokableSymbol.restParam == null ? 0 : 1);
                    BVarSymbol paramSymbol = getParamSymbol(invokableSymbol, argIndex, requiredParamCount, defaultableParamCount);
                    addTaintError(argExpr.pos, paramSymbol.name.value, DiagnosticCode.TAINTED_VALUE_PASSED_TO_SENSITIVE_PARAMETER);
                } else if (taintRecord.taintError != null && taintRecord.taintError.size() > 0) {
                    // This is when current parameter is derived to be sensitive. The error already generated
                    // during taint-table generation will be used.
                    addTaintError(taintRecord.taintError);
                } else {
                    // status of all returns to get accumulated tainted status of all returns for the invocation.
                    for (int returnIndex = 0; returnIndex < returnTaintedStatus.size(); returnIndex++) {
                        if (taintRecord.retParamTaintedStatus.get(returnIndex)) {
                            returnTaintedStatus.set(returnIndex, true);
                        }
                    }
                }
                if (stopAnalysis) {
                    break;
                }
            }
        }
    }
    if (invocationExpr.expr != null) {
        // When an invocation like stringValue.trim() happens, if stringValue is tainted, the result will
        // also be tainted.
        // TODO: TaintedIf annotation, so that it's possible to define what can taint or untaint the return.
        invocationExpr.expr.accept(this);
        for (int i = 0; i < returnTaintedStatus.size(); i++) {
            if (getObservedTaintedStatus()) {
                returnTaintedStatus.set(i, getObservedTaintedStatus());
            }
        }
    }
    taintedStatusList = returnTaintedStatus;
}
Also used : ArrayList(java.util.ArrayList) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) TaintRecord(org.wso2.ballerinalang.compiler.semantics.model.symbols.TaintRecord) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression) BLangEndpoint(org.wso2.ballerinalang.compiler.tree.BLangEndpoint) BVarSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol)

Example 12 with BInvokableSymbol

use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol in project ballerina by ballerina-lang.

the class TypeChecker method checkInvocationParam.

private List<BType> checkInvocationParam(BLangInvocation iExpr) {
    List<BType> paramTypes = ((BInvokableType) iExpr.symbol.type).getParameterTypes();
    int requiredParamsCount;
    if (iExpr.symbol.tag == SymTag.VARIABLE) {
        // Here we assume function pointers can have only required params.
        // And assume that named params and rest params are not supported.
        requiredParamsCount = paramTypes.size();
    } else {
        requiredParamsCount = ((BInvokableSymbol) iExpr.symbol).params.size();
    }
    // Split the different argument types: required args, named args and rest args
    int i = 0;
    BLangExpression vararg = null;
    for (BLangExpression expr : iExpr.argExprs) {
        switch(expr.getKind()) {
            case NAMED_ARGS_EXPR:
                iExpr.namedArgs.add((BLangNamedArgsExpression) expr);
                break;
            case REST_ARGS_EXPR:
                vararg = expr;
                break;
            default:
                if (i < requiredParamsCount) {
                    iExpr.requiredArgs.add(expr);
                } else {
                    iExpr.restArgs.add(expr);
                }
                i++;
                break;
        }
    }
    return checkInvocationArgs(iExpr, paramTypes, requiredParamsCount, vararg);
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) BInvokableType(org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)

Example 13 with BInvokableSymbol

use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol in project ballerina by ballerina-lang.

the class TypeChecker method checkInvocationArgs.

private List<BType> checkInvocationArgs(BLangInvocation iExpr, List<BType> paramTypes, int requiredParamsCount, BLangExpression vararg) {
    List<BType> actualTypes = getListWithErrorTypes(expTypes.size());
    BInvokableSymbol invocableSymbol = (BInvokableSymbol) iExpr.symbol;
    // Check whether the expected param count and the actual args counts are matching.
    if (requiredParamsCount > iExpr.requiredArgs.size()) {
        dlog.error(iExpr.pos, DiagnosticCode.NOT_ENOUGH_ARGS_FUNC_CALL, iExpr.name.value);
        return actualTypes;
    } else if (invocableSymbol.restParam == null && (vararg != null || !iExpr.restArgs.isEmpty())) {
        dlog.error(iExpr.pos, DiagnosticCode.TOO_MANY_ARGS_FUNC_CALL, iExpr.name.value);
        return actualTypes;
    }
    // formal parameters of the outer function.
    if (iExpr.argExprs.size() == 1 && iExpr.argExprs.get(0).getKind() == NodeKind.INVOCATION) {
        checkExpr(iExpr.requiredArgs.get(0), this.env, ((BInvokableType) invocableSymbol.type).paramTypes);
    } else {
        checkRequiredArgs(iExpr.requiredArgs, paramTypes);
    }
    checkNamedArgs(iExpr.namedArgs, invocableSymbol.defaultableParams);
    checkRestArgs(iExpr.restArgs, vararg, invocableSymbol.restParam);
    if (iExpr.async) {
        return Arrays.asList(this.generateFutureType(invocableSymbol));
    } else {
        return invocableSymbol.type.getReturnTypes();
    }
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)

Example 14 with BInvokableSymbol

use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol in project ballerina by ballerina-lang.

the class Types method checkConnectorEquivalency.

public boolean checkConnectorEquivalency(BType actualType, BType expType) {
    if (actualType.tag != TypeTags.CONNECTOR || expType.tag != TypeTags.CONNECTOR) {
        return false;
    }
    if (isSameType(actualType, expType)) {
        return true;
    }
    BConnectorType expConnectorType = (BConnectorType) expType;
    BConnectorType actualConnectorType = (BConnectorType) actualType;
    // take actions in connectors
    List<BInvokableSymbol> expActions = symResolver.getConnectorActionSymbols(expConnectorType.tsymbol.scope);
    List<BInvokableSymbol> actActions = symResolver.getConnectorActionSymbols(actualConnectorType.tsymbol.scope);
    if (expActions.isEmpty() && actActions.isEmpty()) {
        return true;
    }
    if (expActions.size() != actActions.size()) {
        return false;
    }
    // check every action signatures are matching or not
    for (BInvokableSymbol expAction : expActions) {
        if (actActions.stream().filter(v -> checkActionTypeEquality(expAction, v)).collect(Collectors.toList()).size() != 1) {
            return false;
        }
    }
    return true;
}
Also used : BStructField(org.wso2.ballerinalang.compiler.semantics.model.types.BStructType.BStructField) BInvokableType(org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) BMapType(org.wso2.ballerinalang.compiler.semantics.model.types.BMapType) BLangTypeConversionExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangTypeConversionExpr) BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) BStreamType(org.wso2.ballerinalang.compiler.semantics.model.types.BStreamType) BBuiltInRefType(org.wso2.ballerinalang.compiler.semantics.model.types.BBuiltInRefType) Lists(org.wso2.ballerinalang.util.Lists) BConnectorType(org.wso2.ballerinalang.compiler.semantics.model.types.BConnectorType) ArrayList(java.util.ArrayList) BXMLType(org.wso2.ballerinalang.compiler.semantics.model.types.BXMLType) TypeTags(org.wso2.ballerinalang.compiler.util.TypeTags) HashSet(java.util.HashSet) Flags(org.wso2.ballerinalang.util.Flags) TreeBuilder(org.ballerinalang.model.TreeBuilder) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) Names(org.wso2.ballerinalang.compiler.util.Names) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) BErrorType(org.wso2.ballerinalang.compiler.semantics.model.types.BErrorType) BFutureType(org.wso2.ballerinalang.compiler.semantics.model.types.BFutureType) DiagnosticPos(org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos) BArrayType(org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType) BEnumType(org.wso2.ballerinalang.compiler.semantics.model.types.BEnumType) BLangDiagnosticLog(org.wso2.ballerinalang.compiler.util.diagnotic.BLangDiagnosticLog) BStructType(org.wso2.ballerinalang.compiler.semantics.model.types.BStructType) BUnionType(org.wso2.ballerinalang.compiler.semantics.model.types.BUnionType) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression) BConversionOperatorSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BConversionOperatorSymbol) BSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol) BJSONType(org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType) Set(java.util.Set) BTypeVisitor(org.wso2.ballerinalang.compiler.semantics.model.types.BTypeVisitor) Symbols(org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols) Collectors(java.util.stream.Collectors) BLangNode(org.wso2.ballerinalang.compiler.tree.BLangNode) List(java.util.List) DiagnosticCode(org.ballerinalang.util.diagnostic.DiagnosticCode) InstructionCodes(org.wso2.ballerinalang.programfile.InstructionCodes) BAnyType(org.wso2.ballerinalang.compiler.semantics.model.types.BAnyType) BTableType(org.wso2.ballerinalang.compiler.semantics.model.types.BTableType) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol) Collections(java.util.Collections) SymbolTable(org.wso2.ballerinalang.compiler.semantics.model.SymbolTable) CompilerContext(org.wso2.ballerinalang.compiler.util.CompilerContext) BConnectorType(org.wso2.ballerinalang.compiler.semantics.model.types.BConnectorType) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)

Example 15 with BInvokableSymbol

use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol in project ballerina by ballerina-lang.

the class CodeGenerator method visitFunctionPointerLoad.

private void visitFunctionPointerLoad(BLangExpression fpExpr, BInvokableSymbol funcSymbol) {
    int pkgRefCPIndex = addPackageRefCPEntry(currentPkgInfo, funcSymbol.pkgID);
    int funcNameCPIndex = addUTF8CPEntry(currentPkgInfo, funcSymbol.name.value);
    FunctionRefCPEntry funcRefCPEntry = new FunctionRefCPEntry(pkgRefCPIndex, funcNameCPIndex);
    int funcRefCPIndex = currentPkgInfo.addCPEntry(funcRefCPEntry);
    RegIndex nextIndex = calcAndGetExprRegIndex(fpExpr);
    emit(InstructionCodes.FPLOAD, getOperand(funcRefCPIndex), nextIndex);
}
Also used : FunctionRefCPEntry(org.wso2.ballerinalang.programfile.cpentries.FunctionRefCPEntry) BLangEndpoint(org.wso2.ballerinalang.compiler.tree.BLangEndpoint) RegIndex(org.wso2.ballerinalang.programfile.Instruction.RegIndex)

Aggregations

BInvokableSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)31 BInvokableType (org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType)14 ArrayList (java.util.ArrayList)12 BVarSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol)11 BLangEndpoint (org.wso2.ballerinalang.compiler.tree.BLangEndpoint)10 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)9 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)8 SymbolInfo (org.ballerinalang.langserver.completions.SymbolInfo)7 SymbolEnv (org.wso2.ballerinalang.compiler.semantics.model.SymbolEnv)7 BLangExpression (org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)7 BPackageSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol)6 BTypeSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol)6 List (java.util.List)5 Collectors (java.util.stream.Collectors)5 HashMap (java.util.HashMap)4 BStructSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)4 BAttachedFunction (org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction)4 BLangInvocation (org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation)4 BLangExpressionStmt (org.wso2.ballerinalang.compiler.tree.statements.BLangExpressionStmt)4 CompilerContext (org.wso2.ballerinalang.compiler.util.CompilerContext)4