D成员函数std.process.environment.toAA是否有错误?

时间:2019-01-24 20:18:10

标签: thread-safety environment-variables d

来自/snap/dlang/43/usr/include/dlang/dmd/std/process.d

string[string] toAA() @trusted
{
    import std.conv : to;
    string[string] aa;
    version (Posix)
    {
        auto environ = getEnvironPtr;
        for (int i=0; environ[i] != null; ++i)
        {
            import std.string : indexOf;

            immutable varDef = to!string(environ[i]);
            immutable eq = indexOf(varDef, '=');
            assert(eq >= 0);

            immutable name = varDef[0 .. eq];
            immutable value = varDef[eq+1 .. $];

            // In POSIX, environment variables may be defined more
            // than once.  This is a security issue, which we avoid
            // by checking whether the key already exists in the array.
            // For more info:
            // http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html
            if (name !in aa)  aa[name] = value;
        }
    }
    // ...
}

但是getEnvironPtr()的定义如下:

extern(C) extern __gshared const char** environ;
const(char**) getEnvironPtr() @trusted
{
    return environ;
}

由于使用__gsharedenviron extern变量是可修改的,因此上述代码对我来说似乎不是线程安全的。这是D中的错误吗?还是我可能会误解什么?

1 个答案:

答案 0 :(得分:1)

这是在Posix中执行此操作的唯一方法。该变量标记为const,因此您无法对其进行修改,但是可以声明另一个可以修改相同内存的extern(C)变量。所以不要那样。

D在使事情变得安全方面做了大量工作,但使此事情真正安全的唯一方法是消除extern(C)。还是要摆脱Posix并从头开始在D中重建操作系统。这些都是与问题大小成比例的严厉措施。