代码限定-libc的qsort中有符号和无符号值之间的比较

s

在进行验证时,安全性至关重要的代码(应该在嵌入式设备中执行)被忽略了,但是我看到了GCC和Clang发出的一些警告。由于所涉及的代码来自开源BSD libc,因此警告很容易重现:

$ wget https://raw.githubusercontent.com/freebsd/\
freebsd/af3e10e5a78d3af8cef6088748978c6c612757f0/lib/libc/stdlib/qsort.c

$ gcc -c -Wall -Wsign-compare -DI_AM_QSORT_R -Wall qsort.c

qsort.c: In function 'qsort_r':
qsort.c:45:24: warning: comparison between signed and unsigned 
               integer expressions [-Wsign-compare]

#define MIN(a, b) ((a) < (b) ? a : b)
                        ^
qsort.c:186:6: note: in expansion of macro 'MIN'
  r = MIN(pd - pc, pn - pd - es);
      ^
qsort.c:45:34: warning: signed and unsigned type in conditional 
               expression [-Wsign-compare]
 #define MIN(a, b) ((a) < (b) ? a : b)
                                  ^
qsort.c:186:6: note: in expansion of macro 'MIN'
  r = MIN(pd - pc, pn - pd - es);

要了解这些警告(从GCC和CLang发出)...

  • pdpc并且pn 是指针
  • essize_t(即unsigned

可以说,C的处理有符号实体和无符号实体之间比较的规则可以适当地表达为“不要,因为上帝的爱” [1]

但是在这种情况下,BSD实现qsort比较...

  • 减去两个指针(类型为ptrdiff_t)的结果
  • 减去两个指针的结果,该指针减少了es-,这是无符号的。

为什么unsignedptrdiff_t1(即带符号的1)减去一个值会导致unsigned1?您可以在上面引用的帖子中了解到这一点。可以说,对于单词大小的实体,signed OPERATOR unsigned结果的任何表达式都为unsigned类型。

因此,为了简而言之,为了让GCC和CLang停止抱怨,必须从...开始改变界限。

r = MIN(pd - pc, pn - pd - es);

可以:

r = MIN((unsigned)(pd - pc), pn - pd - es)

或者:

r = MIN(pd - pc, (signed)(pn - pd - es));

问题是...正确的补丁是什么?

[1] “为什么不在C / C ++中混合带符号和无符号的值?” http://blog.regehr.org/archives/268

s

显然我在这里独自一人:-)

我对这个问题的回答来自看待事物的一种非常简单的方式。

如果在左侧应用无符号强制转换,然后重新编译,则目标文件不会更改(通过MD5总和进行验证)。如果改用右侧(签名),则目标文件确实发生更改-这意味着此更改(至少在汇编级别上,对于amd64和sparcs而言)与原始代码有所不同。

简短的答案:我着手转换为unsigned(size_t)。似乎也是苹果公司所做的(感谢指针@alk)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在有符号和无符号之间进行隐式转换的c ++代码安全性

防止有符号和无符号整数逻辑之间的代码重复

C中有符号和无符号字符之间的区别

如何删除相似的经过ref限定的成员函数之间的代码重复?

有符号和无符号字符之间的比较

C编译器如何处理无符号和有符号整数?为什么无符号和有符号算术运算的汇编代码相同?

(:gen-class) 和完全限定的符号

IA32汇编代码,用于从有符号/无符号字符到无符号/有符号整数的类型转换

尽管代码中有限定范围,但宏仅在一张纸上工作,而在其他工作纸上不工作

这段代码有什么问题,我不能将指针和无符号值加在一起吗?

以哈希 (#) 为前缀的符号在 Dart 代码中有什么作用?

有符号和无符号整数表达式与0x80000000之间的比较

C ++有符号和无符号整数表达式之间的比较

c ++:有符号和无符号整数表达式之间的比较

有符号和无符号之间的比较。是static_cast唯一的解决方案吗?

有符号和无符号整数表达式之间的比较

消除有符号和无符号整数表达式之间比较的绝佳方法

警告:有符号和无符号整数表达式之间的比较..如何解决?

无符号位字段值与有符号值的比较

是基本类型的带符号/无符号部分,还是限定符

比较有符号和无符号数字

检测有符号和无符号比较错误

比较有符号和无符号整数安全吗?

需要完全限定符号的Cljs宏

C ++中有符号或无符号int

C ++:<=有符号和无符号之间的冲突

有符号和无符号之间的减法,然后除法

仅带符号的整数的“带符号的和无符号的整数表达式之间的比较”

依赖无符号整数溢出的代码的证明?