StringBuilder.ToString()中的----代表什么?

36

stringbuilder.cs的参考源页面在ToString方法中有以下注释:

if (chunk.m_ChunkLength > 0)
{
    // Copy these into local variables so that they 
    // are stable even in the presence of ----s (hackers might do this)
    char[] sourceArray = chunk.m_ChunkChars;
    int chunkOffset = chunk.m_ChunkOffset;
    int chunkLength = chunk.m_ChunkLength;

这是什么意思?----s 是否是恶意用户可能插入格式化字符串中的内容?


10
我们需要一位黑客来回答这个问题 :) - 54l3d
3
我不是黑客,但我猜----s这个词语可能以s结尾,程序员不想让它太容易被猜到。 - Zohar Peled
3
@54l3d,你的名字看起来像L33Tspeak(一种网络黑客用语)。我打赌你是一个很好询问的人。 - Micteu
2
我猜测当参考源代码被发布时,这个短语(@Jerron Vanneval的回答中提到的“竞态条件”)被省略了,而在原始的微软源代码中它仍然保留着。 - Ross Presser
2
重复的问题,链接为http://stackoverflow.com/questions/30595203/redacted-comments-in-mss-source-code-for-net(这个问题更通用且早些时候就被提出了)。 - leppie
显示剩余4条评论
4个回答

41
发布的参考源代码会经过过滤器,过滤掉源代码中的不良内容。微软程序员在他们的注释中使用禁用词汇,如此新闻所述。开发人员的姓名也是被禁止的,微软希望隐藏他们的身份。这样的单词或姓名将被替换为破折号。
在这种情况下,通过CoreCLR可以看出原来的单词是一个被禁止的词汇:
// 将它们复制到本地变量中,以便即使在存在竞争条件的情况下它们也是稳定的
这段代码是从您在提交到 Github之前查看的原始版本手动编辑而来的。微软还不想指控他们的客户是黑客,最初的代码中说的是“races”,因此变成了“----s” :)

5
“种族”是一个被禁用的词吗?“手动编辑”表示“自动编辑”?因为一个人类编辑者认为“种族”指代“人类种族”似乎有点奇怪。 - xanatos
1
不,从CoreCLR源代码可以看出它并不是。过滤器相当愚蠢,早期版本还存在一个严重的错误,导致源代码被重复发射。它只是盲目地应用了一系列被认为是危险的单词。性别、宗教、种族、政治、亵渎。与Wikipedia指南进行比较。 - Hans Passant
@HansPassant:那不是一条指南……试试这个 - Kevin
嗯,不是他们内容贡献者的指南,而是给读者的指南。OpenCLR有一个贡献指南,但没有提到粗话。如果你说了很多脏话,他们很可能不会注意到你的拉取请求,因为这太麻烦了。 - Hans Passant

23
在CoreCLR存储库中,您有一个更完整的引用:

将它们复制到本地变量中,以便它们即使在竞争条件存在的情况下也是稳定的

Github

基本上是一个线程考虑。

2
为了额外的加分,有人应该在CoreCLR中找到更多的“race condition”出现,并找到相应的“----”出现。 - John Saunders
3
这并不是完整的引述,因为它与仅有 ---- 不同得多。 - hatchet - done with SOverflow
3
我认为这段内容被删除是为了避免透露他们试图避免何种漏洞。如果你想隐藏它,为什么要告诉别人这个漏洞名字有多少字符?请注意,翻译后不包括解释或其他非翻译内容。 - Dan Field
6
可能只是一个过于热心的查找和替换,旨在确保政治正确性(特别是消除种族歧视)。 - user253751
6
我认为“竞态条件”最初被缩写为“race”。即使过滤器不保留字符数,吞掉“condition”也会非常奇怪。 - CodesInChaos
显示剩余6条评论

9

除了@Jeroen提供的出色答案外,这不仅是一个线程考虑。 它是为了防止某人故意创建竞争条件并以此导致缓冲区溢出。 在代码的后面,检查了该本地变量的长度。 如果代码检查可访问变量的长度而不是该变量的长度,则它可能在检查长度和调用wstrcpy之间的时间内在另一个线程中更改:

        // Check that we will not overrun our boundaries. 
        if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
        {
            ///
            /// imagine that another thread has changed the chunk.m_ChunkChars array here!
           /// we're now in big trouble, our attempt to prevent a buffer overflow has been thawrted! 
           /// oh wait, we're ok, because we're using a local variable that the other thread can't access anyway.
            fixed (char* sourcePtr = sourceArray)
                string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
        }
        else
        {
            throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        }
    }
    chunk = chunk.m_ChunkPrevious;
} while (chunk != null);

非常有趣的问题。


2

不要认为情况是这样的 - 有争议的代码将数据复制到本地变量,以防在另一个线程上突变字符串构建器实例时发生意外。

我认为----可能与四个字的脏话有关...


2
真的很好奇,你认为一个骇客可能会用哪个四个字母的脏话来在一个更天真的实现中造成不稳定性? - OJFord

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