PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE

关系表达式可能始终为 False

PORTING 检查器会标识那些可能依赖于不同编译器中特定实施细则的代码。PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE 检查器检测那些根据“char”类型的符号规范将导致关系表达式可能始终为 False 的情况。

漏洞与风险

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

缓解与预防

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

漏洞代码示例

复制
   int has_utf8_byte_order_mark(char *s) {
     return s[0] == 0xEF && s[1] == 0xBB && s[2] == 0xBF;  /* PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE */
   }
   int main() {
     char *s = "\xEF\xBB\xBFHello, World!\n";
     if (has_utf8_byte_order_mark(s)) {
       printf("unicode\n");
     } else {
       printf("not unicode\n");
    }
    return 0;
  }

在本示例中,代码仅会在字符无符号时检测到 UTF-8 字节顺序标记。

修正代码示例 1

复制
   int has_utf8_byte_order_mark(char *s) {
     return s[0] == '\xEF' && s[1] == '\xBB' && s[2] == '\xBF';
   }
   int main() {
     char *s = "\xEF\xBB\xBFHello, World!\n";
     if (has_utf8_byte_order_mark(s)) {
       printf("unicode\n");
     } else {
       printf("not unicode\n");
    }
    return 0;
  }

在本示例中,经修复的代码在比较时使用了字符型字面值,而非整数字面值。

修正代码示例 2

复制
   int has_utf8_byte_order_mark(unsigned char *s) {
     return s[0] == 0xEF && s[1] == 0xBB && s[2] == 0xBF;  
   }
   int main() {
     char *s = "\xEF\xBB\xBFHello, World!\n";
     if (has_utf8_byte_order_mark(s)) {
       printf("unicode\n");
     } else {
       printf("not unicode\n");
    }
    return 0;
  }

在本方法中,使用 unsigned char 代替 char

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。