PORTING.UNSIGNEDCHAR.RELOP

有符号/无符号字符型以及没有符号规范的字符型之间的关系运算符

PORTING 检查器会标识那些可能依赖于不同编译器中特定实施细则的代码。PORTING.UNSIGNEDCHAR.RELOP 检查器检测那些在明确有符号或无符号的字符型以及没有符号规范的字符型之间使用关系运算的情况。

漏洞与风险

char 数据类型并未在 C 标准中进行精确的定义,因此某个实例可能被视为有符号,也可能被视为无符号。某些编译器允许使用编译器选项来转换 char 的符号,但开发人员的最佳做法是始终编写无歧义的代码,以避免移植代码时出现问题。

缓解与预防

始终指定"char"类型是否有符号。最好是使用 typedef 或 #define 定义,然后在各处都严格执行该定义。

漏洞代码示例

复制
   static unsigned char* reference = "Polisen förstärker i Malmö";
   int foo(char* str)
   {
     unsigned char* rptr;
       for( rptr = reference; *ptr && *str; str++, rptr++ )
           if( *str != *rptr )
               return 0;
       return 1;
   }

在本示例中,将入站的隐式有符号字符串与参考的显式有符号字符串进行比较,从而导致出现未定义的行为。

修正代码示例

复制
   #define BYTE unsigned char
   static BYTE* reference = "Polisen förstärker i Malmö";
   int foo(BYTE* str)
   {
     BYTE* rptr;
       for( rptr = reference; *ptr && *str; str++, rptr++ )
           if( *str != *rptr )
               return 0;
   }

在经修复的示例中,使用 #define 中所指定的摘要类型即可让我们确保比较的准确性。