[英]strncpy is replaced by __strncpy_chk and fails
I have a statement 我有一个声明
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
in my application which itself is fine and works well. 在我的应用程序中,它本身很好并且运行良好。 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().
这里data-> m_bin-> data是一个char,调用应用程序确保它后跟一个数据块,该数据块足够大,可以保留strncpy()移交的所有数据。
But when I build this as release using GCC/Linux, this function crashes in __strncpy_chk(). 但是,当我使用GCC / Linux构建此版本时,此函数在__strncpy_chk()中崩溃。 So it seems my strncpy() was replaced by __strncpy_chk() using a wrong length for parameter s1.
因此,似乎我的strncpy()被__strncpy_chk()替换为参数s1使用了错误的长度。
So how can I ensure __strncpy_chk() is called with the correct length for s1? 那么如何确保使用正确的s1长度调用__strncpy_chk()?
Thanks! 谢谢!
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().
这里data-> m_bin-> data是一个char,调用应用程序确保它后跟一个数据块,该数据块足够大,可以保留strncpy()移交的所有数据。
It is unusual that this results in a valid C program. 这导致有效的C程序是不寻常的。 Pointer provenance rules usually imply that this leads to undefined behavior.
指针出处规则通常意味着这会导致未定义的行为。
If the char
is at the end of a struct, it may be possible to use a flexible array member, to make it clearer to the compiler what the intent is. 如果
char
位于结构的末尾,则可以使用灵活的数组成员,以使编译器更清楚意图是什么。
If you do not want to change your sources, you can compile with -U_FORTIFY_SOURCE
or -D_FORTIFY_SOURCE=0
. 如果您不想更改源,可以使用
-U_FORTIFY_SOURCE
或-D_FORTIFY_SOURCE=0
进行编译。 This will disable the replacement of strncpy
with the fortified version. 这将禁用强化版本替换
strncpy
。
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
The address of
operator looks suspicious to me. 操作员的
address of
对我来说很可疑。 I would expect something like: 我希望有类似的东西:
strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);
Or maybe: 或者可能:
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?如何确保使用正确的s1长度调用
__strncpy_chk()
?
Well, you can't per se . 好吧,你本身不能。 This is part of
FORTIFY_SOURCE
and object size checking, and the destination buffer size is used when the compiler can deduce it. 这是
FORTIFY_SOURCE
和对象大小检查的一部分,并且在编译器可以推导出目标缓冲区大小时使用。
You could possibly do something like the following, assuming data
is an array of size sizeData
. 您可以执行以下操作,假设
data
是size 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] = '\0';
You should probably turn on warnings with -Wall
. 您可能应该使用
-Wall
打开警告。 I suspect you should get one for using the address of
operator. 我怀疑你应该得到一个使用运营商的
address of
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.