2

我最近需要在 SQL 中对 varbinary 图像执行 isnull 操作。
到目前为止(异常)正常。我很快编写了一个 C# 程序从我的桌面读取文件 no_image.png,并将字节输出为十六进制字符串。

该程序是这样开始的:

byte[] ba = System.IO.File.ReadAllBytes(@"‪D:\UserName\Desktop\no_image.png");
Console.WriteLine(ba.Length);
// From here, change ba to hex string

由于我之前无数次使用 readallbytes,我觉得没什么大不了的。
令我惊讶的是,我在 ReadAllBytes 上遇到了“NotSupported”异常。

我发现问题是当我右键单击文件时,转到选项卡“安全”,然后复制粘贴对象名称(从右侧开始标记并不准确地向左移动),就会发生这种情况。

而且它只发生在 Windows 8.1(也许是 8)上,但不会发生在 Windows 7 上。

202A

当我输出有问题的字符串时:

public static string ToHexString(string input)
{
    string strRetVal = null;
    System.Text.StringBuilder sb = new System.Text.StringBuilder();

    foreach (char c in input)
    {
        sb.Append(((int)c).ToString("X2"));
    }

    strRetVal = sb.ToString();
    sb.Length = 0;
    sb = null;

    return strRetVal;
} // End Function ToHexString

string str = ToHexString(@"‪D:\UserName\Desktop\cookie.png");
string strRight = " (" + ToHexString(@"D:\UserName\Desktop\cookie.png") + ")"; // Correct value, for comparison

string msg = str + Environment.NewLine + "  " + strRight;
Console.WriteLine(msg);

我明白了:

202A443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67
   (443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67)

首先,当我在 ascii 中查找 20 2A 时,它是 [space] + *

由于我既没有看到空格也没有看到星星,所以当我 google 20 2A 时,我得到的第一件事是德国刑法的第 202a 段 http://dejure.org/gesetze/StGB/202a.html

但我认为这是一个相当不幸的巧合,它实际上是 unicode 控制字符“从左到右嵌入”(U+202A) http://www.fileformat.info/info/unicode/char/202a/index。 htm

这是一个错误,还是一个功能?
我的猜测是,这是一个错误的功能。

4

3 回答 3

3

The issue is that the string does not begin with a letter D at all - it just looks like it does.

It appears that the string is hard-coded in your source file.

If that's the case, then you have pasted the string from the security dialog. Unbeknownst to you, the string you pasted begins with the LRO character. This is an invisible character which tales no space, but tells the renderer to render characters from left-to-right, ignoring the usual rendering.

You just need to delete the character.

To do this, position the cursor AFTER the D in the string. Use the Backspace or Delete to Left key <x] to delete the D. Use the key again to delete the invisible LRO character. One more time to delete the ". Now retype the " and the D.

A similar problem could occur wherever the string came from - e.g. from user input, command line, script file etc.

Note: The security dialog shows the filename beginning with the LRO character to ensure that characters are displayed in the left-to-right order, which is necessary to ensure that the hierarchy is correctly understood when using RTL characters. e.g. a filename c:\folder\path\to\file in Arabic might be c:\folder\مسار/إلى/ملف. The "gotcha" is the Arabic parts read in the other direction so the word "path" according to google translate is مسار, and that is the rightmost word, making it appear is if it was the last element of the path, when in fact it is the element immediately after "c:\folder\".

Because security object paths have an hierarchy which is in conflict with the RTL text layout rules, the security dialog always displays RTL text in LTR mode. That means that the Arabic words will be mangled (letters in wrong order) on the security tab. (Imagine it as if it said "elif ot htap"). So the meaning is just about discernable, but from the point of view of security, the security semantics are preserved.

于 2014-06-04T14:50:04.183 回答
3
于 2014-06-04T13:35:56.357 回答
0

这个问题让我很困扰,确定性函数怎么可能对相同的输入给出 2 个不同的结果?经过一番测试,事实证明答案很简单。

如果您在调试器中查看它,您会发现@"‪D:\UserName\Desktop\cookie.png"(第一次使用 Hex 函数)中的“D”字符与@"D:\UserName\Desktop\cookie.png"(第二次使用)中的字符不同。

您必须使用其他类似“D”的字符,可能是通过不需要的键盘快捷键或弄乱了您的 Visual Studio 字符编码。

它看起来完全一样,但实际上它不是单个 char 9try 来观察ctoHex 函数中的变量。

如果您在第一个示例中更改为正常的“D”,它将正常工作。

于 2014-06-04T13:16:41.253 回答