/// <inheritdoc /> public override void VisitDirectFcnCall(DirectFcnCall x) { // It must be function call, not method call of an object // TODO: Implement method call inside class definition through $this pointer if (x.IsMemberOf == null) { ScopedDeclaration <DRoutine> routine; if (functions.TryGetValue(x.QualifiedName, out routine)) { var phpFunction = routine.Member as PhpFunction; Debug.Assert(phpFunction != null, "It must be function, because it is not called as method of a object"); // It is not possible to determine what function definition has been declared if (!phpFunction.Declaration.IsConditional) { var declaration = phpFunction.Declaration.GetNode() as FunctionDecl; Debug.Assert(declaration != null, "PhpFunction is always in function declaration node"); if (IsPassedByRef(declaration.Signature.FormalParams, x.CallSignature.Parameters)) { occurrenceNodes.Enqueue(x); } } } } base.VisitDirectFcnCall(x); }
private void RewriteSanitizeChannel(Channel sanitizeChannel, DirectFcnCall node) { //Store condition: From(sc) >= l var storeSanitizedValue = sanitizeChannel.Label.Level >= _securityLevel.Level; //Get sanitized value condition: To(sc) >= l ^ l >= min(C) var getSanitizedValue = sanitizeChannel.Label.TargetLevel >= _securityLevel.Level && _securityLevel.Level >= _minInputLevel; if (storeSanitizedValue || getSanitizedValue) { //determine if it should read or store a sanitized value var function = getSanitizedValue && !_isOriginalProgram ? FunctionNames.GetSanitize : FunctionNames.StoreSanitize; //construct a new call var name = new TranslatedQualifiedName(new QualifiedName(new Name(function)), new Span()); var parameters = new List <ActualParam>(); parameters.Add(new ActualParam(new Span(), new LongIntLiteral(new Span(), sanitizeChannel.Id))); parameters.Add(new ActualParam(new Span(), node)); var signature = new CallSignature(parameters, new Span()); //let factory create a new DirectFcnCall AST node. var captureSanitizeCall = (DirectFcnCall)_factory.Call(new Span(), name, signature, node.IsMemberOf); //visit the new call base.VisitDirectFcnCall(captureSanitizeCall); } else { //insert default value var defaultValue = CreateDefaultValue(); base.VisitElement(defaultValue); } }
private static VarLikeConstructUse /*!*/ CreatePropertyVariable(Position pos, CompoundVarUse /*!*/ property, FcnParam parameters) { if (parameters != null) { DirectVarUse direct_use; IndirectVarUse indirect_use; VarLikeConstructUse fcnCall; if ((direct_use = property as DirectVarUse) != null) { QualifiedName method_name = new QualifiedName(new Name(direct_use.VarName.Value), Name.EmptyNames); fcnCall = new DirectFcnCall(pos, method_name, null, property.Position, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } else if ((indirect_use = property as IndirectVarUse) != null) { fcnCall = new IndirectFcnCall(pos, indirect_use.VarNameEx, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } else { fcnCall = new IndirectFcnCall(pos, (ItemUse)property, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } // wrap fcnCall into ItemUse fcnCall = CreateFcnArrayDereference(pos, fcnCall, parameters.Item3); return(fcnCall); } else { return(property); } }
/// <inheritdoc /> public override void VisitDirectFcnCall(DirectFcnCall x) { // Direct method call: $object->method() FindFunctionCall(x); base.VisitDirectFcnCall(x); }
override public void VisitDirectFcnCall(DirectFcnCall x) { _serializer.StartSerialize(typeof(DirectFcnCall).Name, SerializeSpan(x.Span), new NodeObj("Name", x.FullName.Name.ToString()), new NodeObj("OrigianlName", x.FullName.OriginalName.ToString()), new NodeObj("FallbackQualifiedName", x.FullName.FallbackName.ToString())); base.VisitDirectFcnCall(x); _serializer.EndSerialize(); }
/// <summary> /// Visits direct function calls. These elements can be output channels. /// </summary> /// <param name="node"></param> public override void VisitDirectFcnCall(DirectFcnCall node) { var outputLabel = FindOutputLabel(node); if (outputLabel != null) { var channel = new Channel() { Id = _uniqueId, Label = outputLabel, Location = new PhpSourceLocation(node.Span) }; OutputChannels.Add(channel); _uniqueId++; } var sanitizeLabel = FindSanitizeLabel(node); if (sanitizeLabel != null) { var channel = new Channel() { Id = _uniqueId, Label = sanitizeLabel, Location = new PhpSourceLocation(node.Span) }; SanitizeChannels.Add(channel); _uniqueId++; } base.VisitDirectFcnCall(node); }
public override void VisitDirectFcnCall(DirectFcnCall node) { var outputChannel = FindChannel(node, _outputChannels); var sanitizeChannel = FindChannel(node, _sanitizeChannels); if (outputChannel != null) { RewriteOutputChannel(outputChannel, node); _visitedChannels.Add(outputChannel.Id); } else if (sanitizeChannel != null) { //keep track of visited channels to prevent infinite recursion if (!_visitedChannels.Contains(sanitizeChannel.Id)) { _visitedChannels.Add(sanitizeChannel.Id); //rewrite sanitize channel RewriteSanitizeChannel(sanitizeChannel, node); } else { base.VisitDirectFcnCall(node); } } else { //no special treatment for this function call base.VisitDirectFcnCall(node); } }
public override void VisitDirectFcnCall(DirectFcnCall x) { VisitSpecificElementProlog(); SerializeToken(nameof(x.FullName), x.FullName.Name.ToString(), x.NameSpan); base.VisitDirectFcnCall(x); }
public override void VisitDirectFcnCall(DirectFcnCall x) { var arguments = CreateArguments(x.CallSignature); var thisObj = GetMemberOf(x); Result(new FunctionCallPoint(x, thisObj, arguments)); }
/// <summary> /// Return all nodes with references to functions that occur within a given function body. /// </summary> /// <returns>References of functions within a given function body.</returns> public DirectFcnCall[] GetReferences() { var couplings = new DirectFcnCall[currentReferences.Count]; // Copy result to an array to make it immutable currentReferences.Values.CopyTo(couplings, 0); return(couplings); }
/// <inheritdoc /> public override void VisitDirectFcnCall(DirectFcnCall x) { if (IsSearched(x.QualifiedName)) { occurrenceNodes.Enqueue(x); } base.VisitDirectFcnCall(x); }
public override void VisitDirectFcnCall(DirectFcnCall x) { VisitElement(x.IsMemberOf); // Force traversing foreach (var param in x.CallSignature.Parameters) { VisitElement(param); } }
/// <summary> /// Add found reference to a function used within the currently traversed function body. /// </summary> /// <param name="x">Reference to standard function.</param> private void AddCoupling(DirectFcnCall x) { Debug.Assert(isInsideFunction, "Function declared inside function is not traversed"); // Presence of itself is not taken into account // Function names are case-insensitive if (!x.QualifiedName.Equals(currentFunction.QualifiedName)) { currentReferences[x.QualifiedName] = x; } }
private void RewriteOutputChannel(Channel outputChannel, DirectFcnCall node) { //the original program (P') captures all output values if (_isOriginalProgram || outputChannel.Label.Level == _securityLevel.Level || _securityLevel.Level < _minInputLevel) { var functionName = _securityLevel.Level < _minInputLevel ? FunctionNames.CaptureOutput : FunctionNames.StoreOutput; //construct a new call to the capture output function var name = new TranslatedQualifiedName(new QualifiedName(new Name(functionName)), new Span()); var parameters = new List <ActualParam>(); parameters.Add(new ActualParam(new Span(), new LongIntLiteral(new Span(), outputChannel.Id))); if (node.CallSignature.Parameters.Length > 0) { parameters.Add(node.CallSignature.Parameters[0]); } var signature = new CallSignature(parameters, new Span()); //let factory create a new DirectFcnCall AST node. var storeOutputCall = (DirectFcnCall)_factory.Call(new Span(), name, signature, node.IsMemberOf); //visit the new call base.VisitDirectFcnCall(storeOutputCall); } //performing an output to an output channel is only allowed if the current execution has the same security level if (_isOriginalProgram || outputChannel.Label.Level == _securityLevel.Level) { //add a semicolon between the new call and the original call base.VisitEmptyStmt((EmptyStmt)_factory.EmptyStmt(new Span(0, 1))); if (!_isOriginalProgram) { //construct a new call to the get output function var name = new TranslatedQualifiedName(new QualifiedName(new Name(FunctionNames.GetOutput)), new Span()); var parameters = new List <ActualParam> { new ActualParam(new Span(), new LongIntLiteral(new Span(), outputChannel.Id)) }; var signature = new CallSignature(parameters, new Span()); //let factory create a new DirectFcnCall AST node. var readOutputCall = (DirectFcnCall)_factory.Call(new Span(), name, signature, node.IsMemberOf); //replace parameter with a read_output call node.CallSignature.Parameters[0] = new ActualParam(new Span(), readOutputCall); //visit the original call base.VisitDirectFcnCall(node); } } }
/// <summary> /// Visit function call actual parameters. /// </summary> /// <param name="x"></param> virtual public void VisitDirectFcnCall(DirectFcnCall x) { VisitFunctionCall(x); }
private static MethodCallExpression ToMethodCallExpression(DirectFcnCall e) { return(new MethodCallExpression(ToNameOfMethod(e.FullName.OriginalName), Parse(e.IsMemberOf), ToCallSignature(e.CallSignature))); }
private static FunctionCallExpression ToFunctionCallExpression(DirectFcnCall e) { return(new FunctionCallExpression(ToNameOfFunction(e.FullName.OriginalName), ToCallSignature(e.CallSignature))); }
/// <inheritdoc /> public override void VisitDirectFcnCall(DirectFcnCall x) { // Direct method call: $object->method() FindUndefinedMembersUse(x); base.VisitDirectFcnCall(x); }
private static VarLikeConstructUse /*!*/ CreateVariableUse(Position pos, VarLikeConstructUse /*!*/ variable, VarLikeConstructUse /*!*/ property, FcnParam parameters, VarLikeConstructUse chain) { if (parameters != null) { if (property is ItemUse) { property.IsMemberOf = variable; property = new IndirectFcnCall(pos, property, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } else { DirectVarUse direct_use; if ((direct_use = property as DirectVarUse) != null) { QualifiedName method_name = new QualifiedName(new Name(direct_use.VarName.Value), Name.EmptyNames); property = new DirectFcnCall(pos, method_name, null, property.Position, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } else { IndirectVarUse indirect_use = (IndirectVarUse)property; property = new IndirectFcnCall(pos, indirect_use.VarNameEx, (List <ActualParam>)parameters.Item2, (List <TypeRef>)parameters.Item1); } property.IsMemberOf = variable; } // wrap into ItemUse property = CreateFcnArrayDereference(pos, property, parameters.Item3); } else { property.IsMemberOf = variable; } if (chain != null) { // finds the first variable use in the chain and connects it to the property VarLikeConstructUse first_in_chain = chain; for (;;) { first_in_chain = DereferenceFunctionArrayAccess(first_in_chain); if (first_in_chain.IsMemberOf != null) { first_in_chain = first_in_chain.IsMemberOf; } else { break; } } first_in_chain.IsMemberOf = property; return(chain); } else { return(property); } }
/// <inheritdoc /> public override void VisitDirectFcnCall(DirectFcnCall x) { RValueResult(x); }
/// <inheritdoc /> override public void VisitDirectFcnCall(DirectFcnCall x) { result = new DirectFcnCall(x.Position, x.QualifiedName, null, x.NamePosition, x.CallSignature.Parameters, x.CallSignature.GenericParams); }
/// <summary> /// Recursive method used for generating the body of text representation of controlflow graph. /// It generates the result for globalcode and dureing the generation it calls /// itself resursivly on controlflow graphs of declared functions and methods. /// </summary> /// <param name="counter">Body of string representation in dot language of current conftrolflow graph.</param> /// <returns></returns> private string generateText(int counter) { string result = ""; List <BasicBlock> nodes = CollectAllBasicBlocks(); /* * generating text for all nodes */ string functionsResult = ""; int i = counter; int oldCounter = counter; foreach (var node in nodes) { string label = ""; foreach (var statement in node.Statements) { /* * recursive generating cfg and text representation for function */ if (statement.GetType() == typeof(FunctionDecl)) { FunctionDecl function = (FunctionDecl)statement; label += "function " + function.Function.Name + Environment.NewLine; try { ControlFlowGraph cfg = new ControlFlowGraph(globalCode, function, File); functionsResult += cfg.generateText((counter / 10000 + 1) * 10000); counter += 10000; } catch (Weverca.ControlFlowGraph.ControlFlowException e) { Console.WriteLine(e.Message); return(""); } } /* * recursive generating cfg and text representation for objects */ else if (statement.GetType() == typeof(TypeDecl)) { TypeDecl clas = (TypeDecl)statement; label += "class " + clas.Name.ToString() + Environment.NewLine; foreach (var method in clas.Members) { if (method.GetType() == typeof(MethodDecl)) { try { ControlFlowGraph cfg = new ControlFlowGraph(globalCode, method as MethodDecl, File); functionsResult += cfg.generateText((counter / 10000 + 1) * 10000); counter += 10000; } catch (Weverca.ControlFlowGraph.ControlFlowException e) { Console.WriteLine(e.Message); return(""); } } } } else if (statement is ForeachStmt) { var forEach = statement as ForeachStmt; Position foreachHeadPosition = new Position(forEach.Position.FirstLine, forEach.Position.FirstColumn, forEach.Position.FirstOffset, forEach.Body.Position.FirstLine, forEach.Body.Position.FirstColumn, forEach.Body.Position.FirstOffset - 1); label += globalCode.SourceUnit.GetSourceCode(foreachHeadPosition) + Environment.NewLine; } else { label += globalCode.SourceUnit.GetSourceCode(statement.Position) + Environment.NewLine; } } if (node.EndIngTryBlocks.Count > 0) { label += "//ending Try block"; } label = label.Replace("\"", "\\\""); result += "node" + i + "[label=\"" + label + "\"]" + Environment.NewLine; i++; } /* * drawing edges */ i = oldCounter; foreach (var node in nodes) { foreach (var e in node.OutgoingEdges) { int index = oldCounter + nodes.IndexOf(e.To); if (e.EdgeType == BasicBlockEdgeTypes.CONDITIONAL) { string label = ""; //in case a condition is not from original ast and hes been aded in constructiion of cfg, we need to write it in different way if (!e.Condition.Position.IsValid || this.cfgAddedElements.Contains(e.Condition)) { if (e.Condition.GetType() == typeof(BoolLiteral)) { label = e.Condition.Value.ToString(); } if (e.Condition.GetType() == typeof(BinaryEx)) { BinaryEx bin = (BinaryEx)e.Condition; //dirty trick how to acces internal field var a = bin.GetType().GetField("operation", BindingFlags.NonPublic | BindingFlags.Instance); if ((Operations)a.GetValue(bin) == Operations.Equal) { Expression l = (Expression)bin.GetType().GetField("leftExpr", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bin); Expression r = (Expression)bin.GetType().GetField("rightExpr", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bin); if (l.Position.IsValid == false) { if (l.GetType() == typeof(IntLiteral)) { label += "" + ((IntLiteral)l).Value; label += "="; label += globalCode.SourceUnit.GetSourceCode(r.Position); } else { label += "else"; } } else { label += globalCode.SourceUnit.GetSourceCode(l.Position); label += "="; label += globalCode.SourceUnit.GetSourceCode(r.Position); } } else { label += "else"; //label = globalCode.SourceUnit.GetSourceCode(edge.Condition.Position); } } if (e.Condition.GetType() == typeof(DirectFcnCall)) { DirectFcnCall functionCall = (DirectFcnCall)e.Condition; label += functionCall.QualifiedName + "("; foreach (var parameter in functionCall.CallSignature.Parameters) { if (parameter.Expression.GetType() == typeof(StringLiteral)) { StringLiteral literal = (StringLiteral)parameter.Expression; label += "\"" + literal.Value + "\"" + ","; } else { label += globalCode.SourceUnit.GetSourceCode(parameter.Expression.Position) + ","; } } label += ")"; } } else { label = globalCode.SourceUnit.GetSourceCode(e.Condition.Position); } label = label.Replace("\"", "\\\""); result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"" + label + "\"]" + Environment.NewLine; } else if (e.EdgeType == BasicBlockEdgeTypes.FOREACH) { result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"foreach special edge\"]" + Environment.NewLine; } else { result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"direct edge\"]" + Environment.NewLine; } } if (node.DefaultBranch != null) { string elseString = string.Empty; if (node.OutgoingEdges.Count > 0) { elseString = "else"; } int index = oldCounter + nodes.IndexOf(node.DefaultBranch.To); result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\" " + elseString + " \"]" + Environment.NewLine; } if (node.EndIngTryBlocks.Count > 0) { foreach (var tryblock in node.EndIngTryBlocks) { foreach (var catchblock in tryblock.catchBlocks) { int index = oldCounter + nodes.IndexOf(catchblock); result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\" catched " + catchblock.ClassName.QualifiedName.Name.Value + " \"]" + Environment.NewLine; } } } i++; } result += functionsResult; result += Environment.NewLine; return(result); }
/// <summary> /// Initializes a new instance of the <see cref="FunctionCallPoint" /> class. /// </summary> /// <param name="functionCall">Function call expression</param> /// <param name="thisObj">Program point with an object if the subroutine is method</param> /// <param name="arguments">Program points with arguments of function call</param> internal FunctionCallPoint(DirectFcnCall functionCall, ValuePoint thisObj, ValuePoint[] arguments) : base(thisObj, functionCall.CallSignature, arguments) { FunctionCall = functionCall; }
public override void VisitDirectFcnCall(DirectFcnCall x) { VisitIsMemberOf(x.IsMemberOf); VisitQualifiedName(x.FullName.OriginalName); VisitCallSignature(x.CallSignature); }
/// <summary> /// Check if the AST node is a sanitize channel according to the active policy. /// </summary> /// <param name="node"></param> /// <returns></returns> private ChannelLabel FindSanitizeLabel(DirectFcnCall node) { var functionName = node.FullName.Name.QualifiedName.Name.Value; return(_policy.Sanitize.FirstOrDefault(channel => channel.Name.Equals(functionName))); }