开发者

Forge a string reference

Is it possible for a caller of the following method to craft a st开发者_开发百科ring reference and pass it as token such that the method returns true? (Assuming the caller does not get the string reference from the static field using reflection.)

class GuessTheSecret
{
    private static readonly string Secret = new string("Secret".ToCharArray());

    public static bool IsCorrect(string token)
    {
        return object.ReferenceEquals(token, Secret);
    }
}


No. You'd have to expose the static instance to the caller. Reference equality means that it is exactly the same object. Unless there is a way to access that particular object, you can't have another that references the same memory. If you were to use the equality operator, that would be different as string overloads that to do value equality rather than reference equality.

Had you, on the other hand, set the static instance value to a constant, you could (by using the constant) have a reference that is equal to the static instance. That is because string literals are interned and shared through out the code, meaning that all string literals that are the same have the same reference.

For example,

class GuessTheSecret
{
    private static readonly string Secret = "Secret";

    public static bool IsCorrect(string token)
    {
        return object.ReferenceEquals(token, Secret);
    }
}

Console.WriteLine( GuessTheSecret.IsCorrect( "Secret" ) );

would output True


I believe is "it depends", basically on whether the caller is passing a same-assembly string that was interned with your string.

Here's why:

ReferenceEquals does what you think, comparing memory locations and not object value (MSDN):

By calling the ReferenceEquals method, you can see that the two strings actually refer to the same object in memory.

There's a C# feature called string interning which according to Eric Lippert:

If you have two identical string literals in one compilation unit then the code we generate ensures that only one string object is created by the CLR for all instances of that literal within the assembly. This optimization is called "string interning".

However, from the same post, interning by default is not guaranteed for each and every string:

If you were writing a compiler in C#, or had some other application in which you felt that it was worth your while to ensure that thousands of identical strings do not consume lots of memory, you can force the runtime to intern your string with the String.Intern method.

Conversely, if you hate interning with an unreasoning passion, you can force the runtime to turn off all string interning in an assembly with the CompilationRelaxation attribute.

Whatever you're trying to accomplish, this current implementation you have seems unreliable at best- I'd consider rethinking what you're doing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜