strncpy 被替换为 __strncpy_chk 并失败
strncpy is replaced by __strncpy_chk and fails
我有一个说法
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
在我的应用程序中,它本身很好并且运行良好。这里的 data->m_bin->data 是一个字符,调用应用程序确保它后面跟着一个数据块,该数据块足够大以保存 strncpy() 传递的所有数据。
但是当我使用 GCC/Linux 将其构建为发行版时,此函数在 __strncpy_chk() 中崩溃。所以我的 strncpy() 似乎被 __strncpy_chk() 替换了,参数 s1 的长度错误。
那么如何确保 __strncpy_chk() 被调用时 s1 的长度正确?
谢谢!
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
address of
操作员在我看来很可疑。我希望是这样的:
strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);
或者也许:
strncpy(&data->m_bin->data[0],versionStr,data->m_bin->sizeData);
how can I ensure __strncpy_chk()
is called with the correct length for s1?
嗯,你不能本身。这是 FORTIFY_SOURCE
和对象大小检查的一部分,目标缓冲区大小在编译器可以推断出来时使用。
假设 data
是一个大小为 sizeData
.
的数组,您可以执行如下操作
/* avoid undefined behavior */
ASSERT(data->m_bin->data != NULL);
ASSERT(versionStr != NULL);
ASSERT(data->m_bin->sizeData > 0);
size_t l1 = data->m_bin->sizeData;
size_t l2 = strlen(versionStr);
/* min function */
size_t len = l1 < l2 ? l1 : l2;
/* if versionStr is shorter than len, then data will be backfilled */
strncpy(data->m_bin->data, versionStr, len);
/* NULL terminate, even if it truncates */
data->m_bin->data[data->m_bin->sizeData-1] = '[=12=]';
您可能应该使用 -Wall
打开警告。我怀疑你应该得到一个使用 address of
运算符的。
Here data->m_bin->data is a char where the calling application ensures it is followed by a datablock which is large enough to keep all the data handed over by strncpy().
这导致有效的 C 程序是不寻常的。指针出处规则通常意味着这会导致未定义的行为。
如果 char
位于结构的末尾,则可以使用灵活的数组成员,使编译器更清楚其意图。
如果您不想更改源代码,可以使用-U_FORTIFY_SOURCE
或-D_FORTIFY_SOURCE=0
进行编译。这将禁止用强化版本替换 strncpy
。
我有一个说法
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
在我的应用程序中,它本身很好并且运行良好。这里的 data->m_bin->data 是一个字符,调用应用程序确保它后面跟着一个数据块,该数据块足够大以保存 strncpy() 传递的所有数据。
但是当我使用 GCC/Linux 将其构建为发行版时,此函数在 __strncpy_chk() 中崩溃。所以我的 strncpy() 似乎被 __strncpy_chk() 替换了,参数 s1 的长度错误。
那么如何确保 __strncpy_chk() 被调用时 s1 的长度正确?
谢谢!
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
address of
操作员在我看来很可疑。我希望是这样的:
strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);
或者也许:
strncpy(&data->m_bin->data[0],versionStr,data->m_bin->sizeData);
how can I ensure
__strncpy_chk()
is called with the correct length for s1?
嗯,你不能本身。这是 FORTIFY_SOURCE
和对象大小检查的一部分,目标缓冲区大小在编译器可以推断出来时使用。
假设 data
是一个大小为 sizeData
.
/* avoid undefined behavior */
ASSERT(data->m_bin->data != NULL);
ASSERT(versionStr != NULL);
ASSERT(data->m_bin->sizeData > 0);
size_t l1 = data->m_bin->sizeData;
size_t l2 = strlen(versionStr);
/* min function */
size_t len = l1 < l2 ? l1 : l2;
/* if versionStr is shorter than len, then data will be backfilled */
strncpy(data->m_bin->data, versionStr, len);
/* NULL terminate, even if it truncates */
data->m_bin->data[data->m_bin->sizeData-1] = '[=12=]';
您可能应该使用 -Wall
打开警告。我怀疑你应该得到一个使用 address of
运算符的。
Here data->m_bin->data is a char where the calling application ensures it is followed by a datablock which is large enough to keep all the data handed over by strncpy().
这导致有效的 C 程序是不寻常的。指针出处规则通常意味着这会导致未定义的行为。
如果 char
位于结构的末尾,则可以使用灵活的数组成员,使编译器更清楚其意图。
如果您不想更改源代码,可以使用-U_FORTIFY_SOURCE
或-D_FORTIFY_SOURCE=0
进行编译。这将禁止用强化版本替换 strncpy
。