use of org.wso2.ballerinalang.compiler.tree.BLangVariable in project ballerina by ballerina-lang.
the class TaintAnalyzer method visit.
public void visit(BLangReturn returnNode) {
List<Boolean> returnTaintedStatus = new ArrayList<>();
if (returnNode.namedReturnVariables == null) {
// If named returns are not used, evaluate each expression to identify the tainted status.
for (BLangExpression expr : returnNode.exprs) {
expr.accept(this);
returnTaintedStatus.addAll(taintedStatusList);
}
} else {
// If named returns are used, report back the tainted status of each variable.
for (BLangVariable var : returnNode.namedReturnVariables) {
returnTaintedStatus.add(var.symbol.tainted);
}
}
if (returnTaintedStatusList == null) {
returnTaintedStatusList = returnTaintedStatus;
} else {
// collective tainted status of returns.
for (int i = 0; i < returnTaintedStatusList.size(); i++) {
if (returnTaintedStatus.size() > i && returnTaintedStatus.get(i)) {
returnTaintedStatusList.set(i, true);
}
}
}
taintedStatusList = returnTaintedStatusList;
}
use of org.wso2.ballerinalang.compiler.tree.BLangVariable in project ballerina by ballerina-lang.
the class TaintAnalyzer method analyzeReturnTaintedStatus.
private void analyzeReturnTaintedStatus(Map<Integer, TaintRecord> taintTable, BLangInvokableNode invokableNode, SymbolEnv symbolEnv, int paramIndex, int requiredParamCount, int defaultableParamCount) {
resetTaintedStatusOfVariables(invokableNode.requiredParams);
resetTaintedStatusOfVariableDef(invokableNode.defaultableParams);
if (invokableNode.restParam != null) {
resetTaintedStatusOfVariables(Arrays.asList(new BLangVariable[] { invokableNode.restParam }));
}
// Mark the given parameter "tainted".
if (paramIndex != ALL_UNTAINTED_TABLE_ENTRY_INDEX) {
if (paramIndex < requiredParamCount) {
invokableNode.requiredParams.get(paramIndex).symbol.tainted = true;
} else if (paramIndex < requiredParamCount + defaultableParamCount) {
invokableNode.defaultableParams.get(paramIndex - requiredParamCount).var.symbol.tainted = true;
} else {
invokableNode.restParam.symbol.tainted = true;
}
}
analyzeReturnTaintedStatus(invokableNode, symbolEnv);
if (taintErrorSet.size() > 0) {
// When invocation returns an error (due to passing a tainted argument to a sensitive parameter) add current
// error to the table for future reference.
taintTable.put(paramIndex, new TaintRecord(null, new ArrayList<>(taintErrorSet)));
taintErrorSet.clear();
} else if (this.blockedNode == null) {
if (invokableNode.retParams.size() == 0) {
returnTaintedStatusList = new ArrayList<>();
} else {
updatedReturnTaintedStatusBasedOnAnnotations(invokableNode.retParams);
}
taintTable.put(paramIndex, new TaintRecord(returnTaintedStatusList, null));
}
}
use of org.wso2.ballerinalang.compiler.tree.BLangVariable in project ballerina by ballerina-lang.
the class TaintAnalyzer method attachTaintTableBasedOnAnnotations.
private void attachTaintTableBasedOnAnnotations(BLangInvokableNode invokableNode) {
if (invokableNode.symbol.taintTable == null) {
// Extract tainted status of the function by lookint at annotations added to returns.
List<Boolean> retParamsTaintedStatus = new ArrayList<>();
for (BLangVariable retParam : invokableNode.retParams) {
retParamsTaintedStatus.add(hasAnnotation(retParam, ANNOTATION_TAINTED));
}
// Append taint table with tainted status when no parameter is tainted.
Map<Integer, TaintRecord> taintTable = new HashMap<>();
taintTable.put(ALL_UNTAINTED_TABLE_ENTRY_INDEX, new TaintRecord(retParamsTaintedStatus, null));
int requiredParamCount = invokableNode.requiredParams.size();
int defaultableParamCount = invokableNode.defaultableParams.size();
int totalParamCount = requiredParamCount + defaultableParamCount + (invokableNode.restParam == null ? 0 : 1);
if (totalParamCount > 0) {
// Append taint table with tainted status when each parameter is tainted.
for (int paramIndex = 0; paramIndex < totalParamCount; paramIndex++) {
BLangVariable param = getParam(invokableNode, paramIndex, requiredParamCount, defaultableParamCount);
// If parameter is sensitive, test for this parameter being tainted is invalid.
if (hasAnnotation(param, ANNOTATION_SENSITIVE)) {
continue;
}
taintTable.put(paramIndex, new TaintRecord(retParamsTaintedStatus, null));
}
}
invokableNode.symbol.taintTable = taintTable;
}
}
use of org.wso2.ballerinalang.compiler.tree.BLangVariable in project ballerina by ballerina-lang.
the class TaintAnalyzer method updatedReturnTaintedStatusBasedOnAnnotations.
private void updatedReturnTaintedStatusBasedOnAnnotations(List<BLangVariable> retParams) {
if (returnTaintedStatusList != null) {
for (int paramIndex = 0; paramIndex < retParams.size(); paramIndex++) {
BLangVariable param = retParams.get(paramIndex);
// Analyzing a function that does not have any return statement and instead have a throw statement.
boolean observedReturnTaintedStatus = false;
if (returnTaintedStatusList.size() > paramIndex) {
observedReturnTaintedStatus = returnTaintedStatusList.get(paramIndex);
}
if (observedReturnTaintedStatus) {
// If return is tainted, but return is marked as untainted, overwrite the value.
if (hasAnnotation(param, ANNOTATION_UNTAINTED)) {
returnTaintedStatusList.set(paramIndex, false);
}
} else {
// If return is not tainted, but return is marked as tainted, overwrite the value.
if (hasAnnotation(param, ANNOTATION_TAINTED)) {
returnTaintedStatusList.set(paramIndex, true);
}
}
}
} else {
returnTaintedStatusList = new ArrayList<>();
}
}
use of org.wso2.ballerinalang.compiler.tree.BLangVariable in project ballerina by ballerina-lang.
the class SemanticAnalyzer method defineResourceEndpoint.
private void defineResourceEndpoint(BLangResource resourceNode, SymbolEnv resourceEnv) {
if (!resourceNode.getParameters().isEmpty()) {
final BLangVariable variable = resourceNode.getParameters().get(0);
if (variable.type == symTable.endpointType) {
String actualVarName = variable.name.value.substring(1);
variable.name = new BLangIdentifier();
variable.name.value = actualVarName;
if (resourceEnv.enclService.endpointType != null) {
variable.type = resourceEnv.enclService.endpointType;
final BEndpointVarSymbol bEndpointVarSymbol = symbolEnter.defineEndpointVarSymbol(variable.pos, EnumSet.noneOf(Flag.class), variable.type, names.fromString(actualVarName), resourceEnv);
variable.symbol = bEndpointVarSymbol;
endpointSPIAnalyzer.populateEndpointSymbol((BStructSymbol) variable.type.tsymbol, bEndpointVarSymbol);
} else {
variable.type = symTable.errType;
variable.symbol = symbolEnter.defineVarSymbol(variable.pos, EnumSet.noneOf(Flag.class), variable.type, names.fromString(actualVarName), resourceEnv);
}
// Replace old symbol with new one.
resourceNode.symbol.params.remove(0);
resourceNode.symbol.params.add(0, variable.symbol);
((BInvokableType) resourceNode.symbol.type).paramTypes.remove(0);
((BInvokableType) resourceNode.symbol.type).paramTypes.add(0, variable.type);
}
}
}
Aggregations