Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetType() can lie?

Tags:

c#

types

Based on the following question asked a few days ago in SO: GetType() and polymorphism and reading Eric Lippert's answer, I started thinking if making GetType() not be virtual really ensured that an object could not lie about its Type.

Specifically, Eric's answer states the following:

The framework designers are not going to add an incredibly dangerous feature such as allowing an object to lie about its type merely to make it consistent with three other methods on the same type.

Now the question is: can I make an object that does lie about its type without it being immediately obvious? I may be profoundly wrong here and I'd love clarification if that is the case, but consider the following code:

public interface IFoo {     Type GetType(); } 

And the following two implementations of said interface:

public class BadFoo : IFoo {     Type IFoo.GetType()     {         return typeof(int);     } }  public class NiceFoo : IFoo { } 

Then if you run the following simple program:

static void Main(string[] args) {     IFoo badFoo = new BadFoo();     IFoo niceFoo = new NiceFoo();     Console.WriteLine("BadFoo says he's a '{0}'", badFoo.GetType().ToString());     Console.WriteLine("NiceFoo says he's a '{0}'", niceFoo.GetType().ToString());     Console.ReadLine(); } 

Sure enough badFoo outputs an erroneous Type.

Now I don't know if this has any serious implications based on Eric describing this behavior as an "incredibly dangerous feature", but could this pattern pose a credible threat?

like image 247
InBetween Avatar asked May 28 '13 08:05

InBetween


People also ask

What is the difference between myemployee GetType() and typeof employee in c#?

typeof keyword takes the Type itself as an argument and returns the underline Type of the argument whereas GetType() can only be invoked on the instance of the type. Employee employee= new Employee(); System. Type t2= employee.

What is GetType?

GetType Method is used to find the type of the current instance. This method returns the instances of the Type class that are used for consideration. Syntax: public Type GetType (); Return Value: This method return the exact runtime type of the current instance.

What is the difference between typeof and GetType?

The only real difference here is that when you want to obtain the type from an instance of your class, you use GetType . If you don't have an instance, but you know the type name (and just need the actual System. Type to inspect or compare to), you would use typeof .

How do I use GetType?

The GetType method is inherited by all types that derive from Object. This means that, in addition to using your own language's comparison keyword, you can use the GetType method to determine the type of a particular object, as the following example shows.


1 Answers

Nice question! The way I see it, you could only really mislead a fellow developer if GetType was virtual on object, which it isn't.

What you did is akin to shadowing GetType, like this:

public class BadFoo {     public new Type GetType()     {         return typeof(int);     } } 

with this class (and using the sample code from the MSDN for the GetType() method) you could indeed have:

int n1 = 12; BadFoo foo = new BadFoo();  Console.WriteLine("n1 and n2 are the same type: {0}",                   Object.ReferenceEquals(n1.GetType(), foo.GetType()));  // output:  // n1 and n2 are the same type: True 

so, yikes, you've successfully lied, right? Well, yes and no... Consider that using this as an exploit would mean using your BadFoo instance as an argument to a method somewhere, that expects likely an object or a common base type for a hierarchy of objects. Something like this:

public void CheckIfInt(object ob) {     if(ob.GetType() == typeof(int))     {         Console.WriteLine("got an int! Initiate destruction of Universe!");     }     else     {         Console.WriteLine("not an int");     } } 

but CheckIfInt(foo) prints "not an int".

So, basically (back to your example), you could really only exploit your "lying type" with code that someone wrote against your IFoo interface, which is very explicit about the fact that it has a "custom" GetType() method.

Only if GetType() was virtual on object you would be able to craft a "lying" type that could be used with methods like CheckIfInt above to create havoc in libraries written by someone else.

like image 121
Paolo Falabella Avatar answered Oct 21 '22 07:10

Paolo Falabella