Exemplo n.º 1
0
		static public string GetSource (Defect defect)
		{
			if (defect == null)
				return String.Empty;

			if (defect.Instruction != null)
				return GetSource (defect.Instruction);

			// rule didn't provide an Instruction but we do our best to
			// find something since this is our only link to the source code

			Instruction candidate;
			TypeDefinition type = null;

			// MethodDefinition, ParameterDefinition
			//	return the method source file with (approximate) line number
			MethodDefinition method = FindMethodFromLocation (defect.Location);
			if (method != null) {
				candidate = ExtractFirst (method);
				if (candidate != null) 
					return FormatSource (candidate);

				// we may still be lucky to find the (a) source file for the type itself
				type = (method.DeclaringType as TypeDefinition);
			}

			// TypeDefinition, FieldDefinition
			//	return the type source file (based on the first ctor)
			if (type == null)
				type = FindTypeFromLocation (defect.Location);
			candidate = ExtractFirst (type);
			if (candidate != null)
				return FormatSource (candidate);

			return String.Empty;
		}
Exemplo n.º 2
0
		private void CheckForLegalCall (MethodDefinition caller, Instruction ins)
		{
			MethodDefinition target = ((MethodReference) ins.Operand).Resolve ();
			if (target != null) {
				ThreadModel callerModel = caller.ThreadingModel ();
				ThreadModel targetModel = target.ThreadingModel ();
				if (!IsValidCall (callerModel, targetModel)) {
					string mesg = string.Format ("{0} {1} cannot call {2} {3}.", callerModel, caller.Name, targetModel, target.Name);
					
					++DefectCount;
					Log.WriteLine (this, "Defect: {0}", mesg);
					Defect defect = new Defect (this, caller, caller, ins, Severity.High, Confidence.High, mesg);
					Runner.Report (defect);
				}
			}
		}
Exemplo n.º 3
0
		// We use this little helper so that we can report a better defect count to the test.
		// (The test itself can't quite manage this because it can't tell what happened
		// inside TearDown if CheckType or CheckMethod failed).
		private void ReportDefect (IMetadataTokenProvider metadata, Severity severity, Confidence confidence, string mesg)
		{
			++DefectCount;
			Log.WriteLine (this, "Defect: {0}", mesg);
			
			// We need to use the Defect Report overload because the runner's current
			// target won't be set if we land here via TearDown.
			Defect defect = new Defect (this, metadata, metadata, severity, confidence, mesg);
			Runner.Report (defect);
		}
Exemplo n.º 4
0
		public override void TearDown ()
		{
			// We don't always know that an anonymous method was used as a thread
			// entry point when we check the method so we check them just before we
			// tear down.
			foreach (MethodDefinition caller in anonymous_entry_points) {
				foreach (Instruction ins in caller.Body.Instructions) {
					switch (ins.OpCode.Code) {
						case Code.Call:
						case Code.Callvirt:
							MethodDefinition target = ((MethodReference) ins.Operand).Resolve ();
							if (target != null) {
								ThreadModel targetModel = target.ThreadingModel ();
								if (targetModel == ThreadModel.MainThread) {
									string mesg = string.Format ("An anonymous thread entry point cannot call MainThread {0}.", target.Name);
									
									++DefectCount;
									Log.WriteLine (this, "Defect: {0}", mesg);
									Defect defect = new Defect (this, caller, caller, ins, Severity.High, Confidence.High, mesg);
									Runner.Report (defect);
								}
							}
							break;
					}
				}
			}
			
			base.TearDown ();
		}
Exemplo n.º 5
0
		private void CheckMethodBody (MethodDefinition method)
		{
			var synchronizedEvents = new Dictionary<MethodReference, List<MethodReference>> ();
			var thisSynchronized = new List<TypeReference> ();
			
			foreach (Instruction ins in method.Body.Instructions) {
				MethodReference candidate = null;
				
				switch (ins.OpCode.Code) {
				case Code.Newobj:
					if (ins.Previous != null && ins.Previous.OpCode.Code == Code.Ldftn) {
						MethodReference ctor = (MethodReference) ins.Operand;
						TypeReference type = ctor.DeclaringType;
						if (type.IsDelegate ()) {
							string nspace = type.Namespace;
							// ldftn entry-point
							// newobj System.Void System.Threading.XXX::.ctor (System.Object,System.IntPtr)
							// i.e. creation of a System.Threading delegate
							if (nspace == "System.Threading") {
								string name = type.Name;
								if (name == "ThreadStart" ||
									name == "ParameterizedThreadStart" ||
									name == "WaitCallback" ||
									name == "WaitOrTimerCallback" ||
									name == "TimerCallback") {
										candidate = (MethodReference) ins.Previous.Operand;
								}
							
							// ldftn entry-point
							// newobj System.Void System.AsyncCallback::.ctor (System.Object,System.IntPtr)
							// i.e. creation of a async delegate
							} else if (nspace == "System") {
								if (type.Name == "AsyncCallback") {
									candidate = (MethodReference) ins.Previous.Operand;
								}
							
							// ldftn entry-point
							// newobj System.Void ThreadedDelegate::.ctor (System.Object,System.IntPtr)
							// i.e. creation of a delegate which is decorated with a threading attribute
							} else if (!ThreadRocks.ThreadedNamespace (nspace)) {
								// Delegates must be able to call the methods they are bound to.
								MethodDefinition target = ((MethodReference) ins.Previous.Operand).Resolve ();
								if (target != null) {
									ThreadModel callerModel = type.ThreadingModel ();
									if (!target.IsGeneratedCode () || target.IsProperty ()) {
										ThreadModel targetModel = target.ThreadingModel ();
										if (!IsValidCall (callerModel, targetModel)) {
											string mesg = string.Format ("{0} delegate cannot be bound to {1} {2} method.", callerModel, targetModel, target.Name);
											
											++DefectCount;
											Log.WriteLine (this, "Defect: {0}", mesg);
											Defect defect = new Defect (this, method, method, ins, Severity.High, Confidence.High, mesg);
											Runner.Report (defect);
										}
										
									} else if (!callerModel.Is (ThreadModel.MainThread)) {
										anonymous_entry_points.Add (target);
									}
								}
							}
						}
					}
					break;
				
				case Code.Call:
				case Code.Callvirt:
					if (!method.IsGeneratedCode () || method.IsProperty ())
						CheckForLegalCall (method, ins);
					
					// ldftn entry-point
					// newobj XXX
					// callvirt System.Void SynchronizedType::add_Name (XXX)	
					// i.e. adding a delegate to an event in a type which uses SynchronizingObject
					MethodReference call = (MethodReference) ins.Operand;
					TypeReference call_type = call.DeclaringType;
					if (ins.Previous.Is (Code.Newobj) && ins.Previous.Previous.Is (Code.Ldftn)) {
						// A few events are blacklisted because they do not use SynchronizingObject and
						// are therefore always threaded.
						if (IsNonSynchronizedSetter (call)) {
							candidate = (MethodReference) ins.Previous.Previous.Operand;
						
						// But most events do use SynchronizingObject and therefore their threading
						// depends on whether and how SynchronizingObject is initialized.
						} else if (HasSynchronizingObject (call_type)) {
							List<MethodReference> methods;
							if (!synchronizedEvents.TryGetValue (call, out methods)) {
								methods = new List<MethodReference> ();
								synchronizedEvents.Add (call, methods);
							}
							
							methods.AddIfNew ((MethodReference) ins.Previous.Previous.Operand);
						
						// Misc threaded events.
						} else if (call_type.FullName == "System.ComponentModel.BackgroundWorker") {
							if (call.Name == "add_DoWork") {
								candidate = (MethodReference) ins.Previous.Previous.Operand;
							}
						}
					
					// callvirt System.Void System.Diagnostics.Process::set_SynchronizingObject (System.ComponentModel.ISynchronizeInvoke)
					} else if (SetSynchronizingObject.Matches (call)) {
						if (ins.Previous.OpCode.Code == Code.Ldarg_0) {
							thisSynchronized.Add (call_type);
						}
					}
					break;
				}
				
				if (candidate != null) {
					Log.WriteLine (this, "{0} is a thread entry point", candidate);
					CheckEntryPoint (candidate);
				}
			}
			
			// For every method added to a threaded event,
			ThreadModel? method_model = null;
			foreach (KeyValuePair<MethodReference, List<MethodReference>> entry in synchronizedEvents) {
				// if the event is synchronized on this then the target must have the same thread
				// as the current method's type or better and it should not be treated as a entry point.
				if (thisSynchronized.Contains (entry.Key.DeclaringType)) {
					if (method_model == null)
						method_model = method.DeclaringType.ThreadingModel ();
					foreach (MethodReference mr in entry.Value) {
						MethodDefinition target = mr.Resolve ();
						if (target != null) {
							ThreadModel targetModel = target.ThreadingModel ();
							if (!IsValidCall (method_model.Value, targetModel)) {
								string mesg = string.Format ("{0} {1} cannot be bound to {2} {3} method.", method_model, entry.Key, targetModel, target.Name);
								ReportDefect (method, Severity.High, Confidence.High, mesg);
							}
						}
					}
				
				// otherwise the method has to be treated as a thread entry point.
				} else {
					foreach (MethodReference mr in entry.Value) {
						Log.WriteLine (this, "{0} is a thread entry point", mr);
						CheckEntryPoint (mr);
					}
				}
			}
		}
Exemplo n.º 6
0
		private void WriteEntry (int index, Defect defect)
		{
			IRule rule = defect.Rule;

			BeginColor (
				(Severity.Critical == defect.Severity || Severity.High == defect.Severity)
				? ConsoleColor.DarkRed : ConsoleColor.DarkYellow);
			writer.WriteLine ("{0}. {1}", index, rule.Name);
			writer.WriteLine ();
			EndColor ();

			BeginColor (ConsoleColor.DarkRed);
			writer.Write ("Problem: ");
			EndColor ();
			writer.Write (rule.Problem);
			writer.WriteLine ();

			writer.WriteLine ("* Severity: {0}, Confidence: {1}", defect.Severity, defect.Confidence);
			writer.WriteLine ("* Target:   {0}", defect.Target);

			if (defect.Location != defect.Target)
				writer.WriteLine ("* Location: {0}", defect.Location);	

			string source = defect.Source;
			if (!String.IsNullOrEmpty (source))
				writer.WriteLine ("* Source:   {0}", source);

			if (!String.IsNullOrEmpty (defect.Text))
				writer.WriteLine ("* Details:  {0}", defect.Text);
			writer.WriteLine ();

			BeginColor (ConsoleColor.DarkGreen);
			writer.Write ("Solution: ");
			EndColor ();
			writer.Write (rule.Solution);
			writer.WriteLine ();

			writer.WriteLine ("More info available at: {0}", rule.Uri.ToString ());
			writer.WriteLine ();
			writer.WriteLine ();
		}
		// reports only if it was called more than one time
		private void DelayedReport (Defect defect)
		{
			reportCounter++;
			if (reportCounter > 1) {
				if (reportCounter == 2)
					Runner.Report (defectDelayed);
				Runner.Report (defect);
			} else
				defectDelayed = defect;
		}
Exemplo n.º 8
0
		internal GendarmeViolation (GF.Defect defect)
		{
			this.defect = defect;
			this.location = new CA.CodeLocation(string.Empty, 0, 0);
		}
Exemplo n.º 9
0
		void CreateElement (Defect defect)
		{
			writer.WriteStartElement ("defect");
			writer.WriteAttributeString ("Severity", defect.Severity.ToString ());
			writer.WriteAttributeString ("Confidence", defect.Confidence.ToString ());
			writer.WriteAttributeString ("Location", defect.Location.ToString ());
			writer.WriteAttributeString ("Source", defect.Source);
			writer.WriteString (defect.Text);
			writer.WriteEndElement ();
		}
Exemplo n.º 10
0
		void CreateElement (Defect defect)
		{
			writer.WriteStartElement ("defect");
			writer.WriteAttributeString ("Severity", defect.Severity.ToString ());
			writer.WriteAttributeString ("Confidence", defect.Confidence.ToString ());
			writer.WriteAttributeString ("Location", defect.Location.ToString ());
			writer.WriteAttributeString ("Source", defect.Source);
            
            String st =null;
            if (defect.Location is MethodDefinition)
                st = "Method";
            else if (defect.Location is FieldDefinition)
                st = "Field";
            else if (defect.Location is ParameterDefinition)
                st = "Parameter";
            else if (defect.Location is TypeDefinition)
                st = "Type";
            else if (defect.Location is MethodReturnType)
                st = "Result";
            if (st != null)
                writer.WriteAttributeString ("SourceType", st);

			writer.WriteString (defect.Text);
			writer.WriteEndElement ();
		}
Exemplo n.º 11
0
		public void Report (MethodDefinition method, Instruction ins, Severity severity, Confidence confidence, string message)
		{
			// check here to avoid creating the Defect object
			if (!Filter (severity, confidence, method))
				return;

			Defect defect = new Defect (currentRule, currentTarget, method, ins, severity, confidence, message);
			Report (defect);
		}
Exemplo n.º 12
0
		public void Report (IMetadataTokenProvider metadata, Severity severity, Confidence confidence, string message)
		{
			// check here to avoid creating the Defect object
			if (!Filter (severity, confidence, metadata))
				return;

			Defect defect = new Defect (currentRule, currentTarget, metadata, severity, confidence, message);
			Report (defect);
		}
Exemplo n.º 13
0
		public virtual void Report (Defect defect)
		{
			if (defect == null)
				throw new ArgumentNullException ("defect");

			if (!Filter (defect.Severity, defect.Confidence, defect.Location))
				return;
				
			if (IgnoreList.IsIgnored (defect.Rule, defect.Target))
				return;

			defect_list.Add (defect);
		}
Exemplo n.º 14
0
 internal GendarmeViolation(GF.Defect defect)
 {
     this.defect   = defect;
     this.location = new CA.CodeLocation(string.Empty, 0, 0);
 }