文章目录

  • 警告
  • strncat
  • -Wstringop-overflow
  • 警告引入
  • 改进
  • glibc strncat 实现
  • 评语

警告

从警告本身说,看着有些不太好理解,就是有些不太好理解;翻译一下说限制5(意思是strncat的第三个参数是5,这个第三个参数就是一个限制长度的参数),和源串的长度相等。相等就相等,为什么报这么个警告呢?很奇怪。
[root@vmtca-2101 test]# gcc warning.c
warning.c: In function ‘main’:
warning.c:13:9: warning: ‘strncat’ specified bound 5 equals source length [-Wstringop-overflow=]
strncat(d, “abcde”, strlen(“abcde”));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

strncat

这个函数在编译时,gcc会使用一下优化选项,记缓存溢出的检查。具体在函数:gimple_fold_builtin_strncat实现;

-Wstringop-overflow

-Wstringop-overflow=type
在使用例如memcpy和strcpy,strcat字符串操作的函数时,如果操作可能导致目的操作缓存溢出,就会报这个警告。The optional argument is one greater than the type of Object Size Checking to perform to determine the size of the destination. See Section 6.56 [Object Size Checking], page 567.
https://blog.csdn.net/qq_36428903/article/details/121440102#Object_Size_Checking_Builtin_Functions_127

The argument is meaningful only for functions that operate on character arrays but not for raw memory functions like memcpy which always make use of Object Size type-0. The option also warns for calls that specify a size in excess of the largest possible object or at most SIZE_MAX / 2 bytes. The option produces the best results with optimization enabled but can detect a small subset of simple buffer overflows even without optimization in calls to the GCC built-in
functions like __builtin_memcpy that correspond to the standard functions. In any case, the option warns about just a subset of buffer overflows detected by the corresponding overflow checking built-ins.

For example, the option will issue a warning for the strcpy call below because it copies at least 5 characters (the string “blue” including the terminating NUL) into the buffer of size 4.

enum Color { blue, purple, yellow };
const char* f (enum Color clr)
{
static char buf [4];
const char *str;
switch (clr)
{
case blue: str = “blue”; break;
case purple: str = “purple”; break;
case yellow: str = “yellow”; break;
}
return strcpy (buf, str); // warning here
}

Option ‘-Wstringop-overflow=2’ is enabled by default.
-Wstringop-overflow
-Wstringop-overflow=1
The ‘-Wstringop-overflow=1’ option uses type-zero Object Size Checking to determine the sizes of destination objects. This is the default setting of the option. At this setting the option will not warn for writes past the end of subobjects of larger objects accessed by pointers unless the size of the largest surrounding object is known. When the destination may be one of several objects it is assumed to be the largest one of them. On Linux systems, when optimization is enabled at this setting the option warns for the same code as when the _FORTIFY_SOURCE macro is defined to a non-zero value.
-Wstringop-overflow=2
The ‘-Wstringop-overflow=2’ option uses type-one Object Size Checking to determine the sizes of destination objects. At this setting the option will warn about overflows when writing to members of the largest complete objects whose exact size is known. It will, however, not warn for excessive writes to the same members of unknown objects referenced by pointers since they may point to arrays containing unknown numbers of elements.
-Wstringop-overflow=3
The ‘-Wstringop-overflow=3’ option uses type-two Object Size Checking to determine the sizes of destination objects. At this setting the option warns about overflowing the smallest object or data member. This is the most restrictive setting of the option that may result in warnings for safe code.
-Wstringop-overflow=4
The ‘-Wstringop-overflow=4’ option uses type-three Object Size Checking to determine the sizes of destination objects. At this setting the option will warn about overflowing any data members, and when the destination is one of several objects it uses the size of the largest of them to decide whether to issue a warning. Similarly to ‘-Wstringop-overflow=3’ this setting of the option may result in warnings for benign code.

警告引入

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81117

commit 025d57f037ad13eb479818b677ef4be4d97b639c
Author: Martin Sebor <msebor@redhat.com>
Date:   Fri Nov 10 16:35:26 2017 +0000PR c/81117 - Improve buffer overflow checking in strncpygcc/ChangeLog:PR c/81117* builtins.c (compute_objsize): Handle arrays thatcompute_builtin_object_size likes to fail for.  Make extern.* builtins.h (compute_objsize): Declare.(check_strncpy_sizes): New function.(expand_builtin_strncpy): Call check_strncpy_sizes.* gimple-fold.c (gimple_fold_builtin_strncpy): Implement-Wstringop-truncation.(gimple_fold_builtin_strncat): Same.* gimple.c (gimple_build_call_from_tree): Set call location.* tree-ssa-strlen.c (strlen_to_stridx): New global variable.(maybe_diag_bound_equal_length, is_strlen_related_p): New functions.(handle_builtin_stxncpy, handle_builtin_strncat): Same.(handle_builtin_strlen): Use strlen_to_stridx.(strlen_optimize_stmt): Handle flavors of strncat, strncpy, andstpncpy.Use strlen_to_stridx.(pass_strlen::execute): Release strlen_to_stridx.* doc/invoke.texi (-Wsizeof-pointer-memaccess): Document enhancement.(-Wstringop-truncation): Document new option.

改进

这里的注释,有解释为什么做这个警告。从这里可以看到,没有任何根据就要上报,目的是为了防止可能的缓存溢出:源串的长度不能等于限定的长度,即使目的的长度不可知(虽然将限定长度设置为源串的长度是普遍做法)。

commit 323026c7dfe23e1093e80f7db5f4851d1a867b62
Author: Siddhesh Poyarekar <siddhesh@gotplt.org>
Date:   Mon Nov 15 23:03:15 2021 +0530gimple-fold: Use ranges to simplify strncat and snprintfUse ranges for lengths and object sizes in strncat and snprintf todetermine if they can be transformed into simpler operations.gcc/ChangeLog:* gimple-fold.c (gimple_fold_builtin_strncat): Use ranges todetermine if it is safe to transform to strcat.(gimple_fold_builtin_snprintf): Likewise.+         /* To avoid possible overflow the specified bound should also
+            not be equal to the length of the source, even when the size
+            of the destination is unknown (it's not an uncommon mistake
+            to specify as the bound to strncpy the length of the source).  */
+         if (warning_at (loc, OPT_Wstringop_overflow_,
+                         "%qD specified bound %E equals source length",
+                         fndecl, len))suppress_warning (stmt, OPT_Wstringop_overflow_);

glibc strncat 实现

这里也是很简单,根据源串指针,及限定长度,求一个字符串长度,也就是如果源串长的话,去n作为最终的值,如果串短,使用短的长度,最后使用memcpy做内存复制。

char *
STRNCAT (char *s1, const char *s2, size_t n)
{char *s = s1;/* Find the end of S1.  */s1 += strlen (s1);size_t ss = __strnlen (s2, n);s1[ss] = '\0';memcpy (s1, s2, ss);return s;
}

评语

这个警告还是有些聒噪。如果可以可以使用snprintf替换。

C: warning: ‘strncat’ specified bound 5 equals source length [-Wstringop-overflow=]相关推荐

  1. 警告warning: strncpy specified bound XX equals destination size

    1.问题 用strncpy字符串拷贝时,出现警告:warning: 'strncpy' specified bound 32 equals destination size [-Wstringop-t ...

  2. Warning message:In a + b : longer object length is not a multiple of shorter object length

    Warning message:In a + b : longer object length is not a multiple of shorter object length 目录 Warnin ...

  3. 移植libibverbs到riscv架构

    编译环境: OS: Ubuntu 20.10LTS x86-linux-gnu: gcc 10.3.0 riscv-unknown-linux-gnu: gcc 9.2.0 1.获取libibverb ...

  4. AD原理图编译WARNING:Net XXX has no driving source

    Altium designer WARNING系列: WARNING:Net XXX has no driving source 这篇博客填一下以前一篇关于Altium designer ERROR的 ...

  5. WARNING:tensorflow:Entity <bound method GRUCell.call of <tensorflow.python.ops.rnn_cell_impl.GRUCell

    错误: WARNING:tensorflow:Entity <bound method GRUCell.call of <tensorflow.python.ops.rnn_cell_im ...

  6. how can i check the error of Journal import date source

    历史记录 ORION_MIGRATION - 2009年10月7日 下午02时19分04秒 问题说明: how can i check the error of Journal import date ...

  7. 字符函数和字符串函数详解(二)strncpy strncat strncmp strstr strtok(及其模拟实现)

     系列文章目录 字符函数和字符串函数详解(一)strlen strcpy strcat strcmp 字符函数和字符串函数详解(二)strncpy strncat strncmp strstr str ...

  8. strcat函数与strncat函数——追加字符串

    头文件: string.h 函数的声明: char *strcat( char *dest, const char *source ) 目标字符串           原始字符串 char *strn ...

  9. C语言strcat、strncat函数详解

    C语言strcat.strncat函数详解 一.strcat函数 1.函数原型 2.函数参数.返回值解析 3.函数作用 4.注意事项 5.strcat函数模拟实现 二.strncat函数 1.函数原型 ...

最新文章

  1. 淘宝前端工程师:国内前端行业十日谈(六)
  2. 【Hibernate】could not instantiate class.. from tuple] with root cause
  3. RBAC模型:设计思路
  4. 小技巧,找出所有check table设置为某个数据库表的数据库表
  5. 数学建模债券投资组合_1998年全国大学生数学建模竞赛题目A题投资的收益和风险.PDF...
  6. 标识为普通SQL语法
  7. 特殊时期,找工作的 9 点建议!
  8. matlab按图像边缘抠图_Ps最全十大抠图方法都在这,最后一种万能「值得收藏」...
  9. 最简单DIY基于STM32F407探索者开发板和PCA9685舵机控制模块的红外遥控机械臂控制程序
  10. Linux安装tomcat8
  11. 如何做无线抄表既SCADA无线数据采集管理系统
  12. 基于python的计算基因组_【ROSALIND】【练Python,学生信】05 计算DNA序列GC含量
  13. matlab的小技巧
  14. Python爬虫入门【8】: 蜂鸟网图片爬取之三
  15. L1-4 拯救外星人
  16. Hides for Mac v5.6一键隐藏所有应用 支持 M1
  17. 使用ROS melodic下 控制真实UR5机器人 手把手教程
  18. Linux从入门到实战 ---- 磁盘分区
  19. linux ftok()
  20. 微软2013暑假实习生笔试题解析

热门文章

  1. 第二章 通信技术(3G4G)演进对车联网的影响
  2. input 限制只能输入英文、中文、字母、小数、表情包等约束
  3. CAD圆与椭圆的初阶练习、CAD扇叶绘制
  4. 雅思阅读真经总纲_雅思天团集训课流程介绍
  5. 基于SSM+VUE整合的音乐购买以及播放器管理系统
  6. 实验三:十进制转换成二进制数(顺序栈)
  7. libvirt-qemu-虚拟机设备热插拔实践
  8. CAS和Shiro内外网双IP动态访问
  9. 各类NFC卡片数据分析辅助工具集
  10. 拉绳位移传感器的线性及干扰有哪些?