gpt4 book ai didi

c++ - 如何使用 FormatMessage 函数填充系统错误消息的 va_list?

转载 作者:行者123 更新时间:2023-11-27 22:59:56 27 4
gpt4 key购买 nike

我不确定我的实现是否存在根本性问题,或者 Windows API 中是否存在关于格式化系统错误消息的错误。

我有一个用于 FormatMessage 函数的 Windows API 包装器方法。我的实现允许调用者传入额外的参数以允许格式化系统错误消息。

方法签名如下:

bool setFormattedMessage(int arguments, ...)

在此方法中,我有以下代码块似乎不适用于我的所有单元测试:

if (arguments)
{
va_list argumentsList;
va_start(argumentsList, arguments);

size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, language, (LPWSTR)&buffer, 0,
&argumentsList);

va_end(argumentsList);
}

注意:codelanguage 是实例化列表中设置的类的成员(使用 GetLastErrorLANGIDFROMLCID(GetThreadLocale()).

下面是一些没有任何问题的单元测试:

如果我为错误代码 34 创建了一个类的实例,如果我将方法调用为 test.setFormattedMessage(0)(请注意,这不会进入由于 if (arguments) 行,我发布的代码块:

The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.`

如果我将方法调用为 test.setFormattedMessage(3, L"C:", L"disk 2", L"ABC123"),我会得到以下信息:

The wrong diskette is in the drive. Insert disk 2 (Volume Serial Number: ABC123) into drive C:.;

但是,对于包含 %hs%08lx 等示例的错误消息,我在尝试格式化文本时遇到了问题。

以错误代码 573 为例。将参数 0 传递到方法时,我得到以下文本(如预期的那样):

{Missing System File} The required system file %hs is bad or missing.

但是,如果我传入 (1, "test"),我会得到:

{Missing System File} The required system file hs is bad or missing.

其实我已经发现,无论我是否传入"test"L"test",都是char的拷贝, wchar_t 等我总是以上面的错误消息结束。创建的消息与传递 (0) 相同,只是从字符串中删除了 %

我发现所有其他参数都存在同样的问题,除非它们被编号(例如 %1)。关于我是否犯了基本错误或者 FormatMessage 函数中确实存在缺陷,我完全陷入了这一点。

我的印象是我可以像为 swprintf 那样传递 %hs 占位符的替换:

char * t = "file 123";
wchar_t a[2000];
int v = swprintf(a, 2000, L"Blah blah %hs", t);
std::wstring someText(a, v);

Blah blah file 123

最佳答案

如果您阅读 FormatMessage() documentation ,它特别指出:

Security Remarks

If this function is called without FORMAT_MESSAGE_IGNORE_INSERTS, the Arguments parameter must contain enough parameters to satisfy all insertion sequences in the message string, and they must be of the correct type. Therefore, do not use untrusted or unknown message strings with inserts enabled because they can contain more insertion sequences than Arguments provides, or those that may be of the wrong type. In particular, it is unsafe to take an arbitrary system error code returned from an API and use FORMAT_MESSAGE_FROM_SYSTEM without FORMAT_MESSAGE_IGNORE_INSERTS.

您的代码使用了 FORMAT_MESSAGE_FROM_SYSTEM 而没有使用 FORMAT_MESSAGE_IGNORE_INSERTS,这是不安全的。

因此,除非绝对确定您知道任何给定系统错误代码的确切格式,并且您的代码在决定哪种格式之前已经检查了该错误代码要传入的参数,并且您绝对确定 Microsoft 永远不会在操作系统版本之间更改该错误消息的格式,那么您根本无法安全地使用带有系统错误的格式化参数,所以甚至不要尝试.只有当您通过 FORMAT_MESSAGE_FROM_HMODULE 使用您自己的错误消息来访问您自己的 EXE/DLL 模块资源,或 FORMAT_MESSAGE_FROM_STRING 在内存。

关于c++ - 如何使用 FormatMessage 函数填充系统错误消息的 va_list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28812988/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com