问题描述
报错代码
函数调用
char macaddr[16] = {0};
get_wifi_mac_from_bin(macaddr);
函数内容
int get_wifi_mac_from_bin(char *macaddr)
{
.....
char mac[16] = {0};
strncpy(macaddr,mac,strlen(mac));
.....
}
报错log
error: '__builtin_strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
问题分析
这是由于编译选项开启了-Wformat-overflow导致的,说明如下
参考链接
Warning Options (Using the GNU Compiler Collection (GCC))
-Wformat-overflow
-Wformat-overflow=level
Warn about calls to formatted input/output functions such as sprintf and vsprintf that might overflow the destination buffer. When the exact number of bytes written by a format directive cannot be determined at compile-time it is estimated based on heuristics that depend on the level argument and on optimization. While enabling optimization will in most cases improve the accuracy of the warning, it may also result in false positives.
-Wformat-overflow
-Wformat-overflow=1
Level 1 of -Wformat-overflow enabled by -Wformat employs a conservative approach that warns only about calls that most likely overflow the buffer. At this level, numeric arguments to format directives with unknown values are assumed to have the value of one, and strings of unknown length to be empty. Numeric arguments that are known to be bounded to a subrange of their type, or string arguments whose output is bounded either by their directive’s precision or by a finite set of string literals, are assumed to take on the value within the range that results in the most bytes on output. For example, the call to sprintf below is diagnosed because even with both a and b equal to zero, the terminating NUL character ('\0') appended by the function to the destination buffer will be written past its end. Increasing the size of the buffer by a single byte is sufficient to avoid the warning, though it may not be sufficient to avoid the overflow.
void f (int a, int b)
{
char buf [13];
sprintf (buf, "a = %i, b = %i\n", a, b);
}
-Wformat-overflow=2
Level 2 warns also about calls that might overflow the destination buffer given an argument of sufficient length or magnitude. At level 2, unknown numeric arguments are assumed to have the minimum representable value for signed types with a precision greater than 1, and the maximum representable value otherwise. Unknown string arguments whose length cannot be assumed to be bounded either by the directive’s precision, or by a finite set of string literals they may evaluate to, or the character array they may point to, are assumed to be 1 character long.
At level 2, the call in the example above is again diagnosed, but this time because with a equal to a 32-bit INT_MIN the first %i directive will write some of its digits beyond the end of the destination buffer. To make the call safe regardless of the values of the two variables, the size of the destination buffer must be increased to at least 34 bytes. GCC includes the minimum size of the buffer in an informational note following the warning.
An alternative to increasing the size of the destination buffer is to constrain the range of formatted values. The maximum length of string arguments can be bounded by specifying the precision in the format directive. When numeric arguments of format directives can be assumed to be bounded by less than the precision of their type, choosing an appropriate length modifier to the format specifier will reduce the required buffer size. For example, if a and b in the example above can be assumed to be within the precision of the short int type then using either the %hi format directive or casting the argument to short reduces the maximum required size of the buffer to 24 bytes.
void f (int a, int b)
{
char buf [23];
sprintf (buf, "a = %hi, b = %i\n", a, (short)b);
}
解决方案
将
strncpy(macaddr,mac,strlen(mac));
修改为
strncpy(macaddr,mac,sizeof(mac)-1);