防止更改String.Empty的值。

12

从好奇心驱使,试图破坏事物的角度来看,也包括防范潜在问题。想象一下通过调用以下代码(或类似的代码,但 string.Empty 是一个很好的例子)可能会发生的最糟糕的情况:

typeof(String).GetField("Empty", 
    BindingFlags.Public | 
    BindingFlags.NonPublic | 
    BindingFlags.Static | 
    BindingFlags.GetField
).SetValue(null, "foo" );

当代码中存在 x = myClass.bar ?? string.Empty 这样的语句时,可能会出现问题。

是否有任何方法(类似于不同的应用程序域或类似方法),可以保护(或检测)某人更改诸如String.EmptySqlDateTime.MinValue(或其他类似的只读字段在.NET中)的值?


相关的吗?https://dev59.com/lFLTa4cB1Zd3GeqPcqwl - harold
8
无法防止受信任的代码执行不良操作。而不受信任的代码无法修改 string.Empty。在这种情况下,自己给自己惹麻烦是非常明显的。 - CodesInChaos
1
顺便问一下,Int.MaxValue 不是一个 常量 字段吗? - harold
7
String.Empty 是 只读 (readonly)的,而不是 常量(const)。这是一项非常重要的运行时优化,直接加载指针,无需进行垃圾回收。快速和安全通常是相互冲突的目标。在 SO 上,很少有程序员会意外损坏 String.Empty,所以这不是一个真正的问题。SO 的 FAQ 需要适用于这里:基于你实际遇到的问题,提出实用且可回答的问题。 - Hans Passant
9
@HansPassant,我猜这不是关于String.Empty的问题,而是这样的代码可能会导致安全问题。只读意味着只读,如果我设置一些哈希密钥或类似的东西,假设没有人会修改它们,那么我将留下一个安全漏洞。我认为.NET运行时应该在运行时保持反射一致性,就像编译时一样。我真的不认为这个问题不符合SO标准,它确实是一个问题。 - Akash Kava
@AkashKava 这怎么成了“安全”问题了?如果你正在加载和运行不受信任的代码到你的进程中,并且让它使用反射API,那么你需要担心的不仅仅是readonly字段被改变,此外,代码已经在密封舱的另一侧 - Dai
1个回答

7
你可以像这样在你的程序集中定义自己的const字段:

internal const string Empty = "";

然后对比 String.Empty 进行检查,但这几乎是徒劳无功的。

你需要在访问 String.Empty 的每个地方执行检查,并有效地替换它(因为你会在比较点进行检查,所以实际上不再使用 String.Empty 而是用你的版本)。

由于它是 const,值不能被更改,这是好的,但同时,如果 String.Empty 的值确实发生了变化(虽然不太可能),你就必须更改你的值,然后重新编译引用该字段的 所有内容

当然,你可以将你的版本设为 readonly,但那样你就容易受到通过反射更改值的攻击,回到起点。

此外,如果更改了String.Empty,不仅会影响对该字段的比较,而且我想BCL中的许多方法都无法正常工作;通过Reflector查看,似乎在mscorlib(.NET 4.0)中仅引用了几百次。

references to String.Empty in mscorlib 4.0

因此,你可以尝试保证该值未更改,但这并不切实际(这将是一场永无休止的猫鼠游戏)。从程序的角度来看,如果 String.Empty 的值被更改,世界将会末日,程序几乎在更改后立即死亡。请注意,保留 HTML 标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接