此代码是否为整数溢出

时间:2016-02-11 21:08:20

标签: c

我在某处看到了这段代码,这不是整数溢出和未定义的行为吗?

假设0 < str[i] < 127

char *msl_decrypt(char *str) {
    char *decrypted;
    unsigned int i;
    int key = 0xFACA;

    for (i = 0; i < strlen(str); ++i) {
        str[i] = str[i] + key; // referring to this line, is it UB?
    }
    ...

1 个答案:

答案 0 :(得分:5)

太糟糕了,你没有指定目标参数。所以对于以下我的假设:

  • CHAR_BIT == 8
  • sizeof(int) >= 2
  • 不填充位
  • str指向有效且已初始化的内存,该内存已正确nul - 终止且不大于INT_MAX(或者使用size_t进行索引 - 感谢@chux)。< / LI>
  • 以及我们倾向于采取的其他先决条件。

这些是大多数现代实施的典型。

对于sizeof(int) == 2,初始化程序是实现定义的行为,因为您使用unsigned int常量作为初始化程序。对于更宽的int,这是可以的。如果(int)(0xFACA) + CHAR_MAX > INT_MAX(算术上,也只与2字节int相关),情况也会变得更加复杂。

其余的以更复杂的方式依赖于实现定义的行为

1)添加str[i] + key:此处str[i]首先转换为int,添加的结果为int,结果为int。< / p>

2)作业str[i] = ...:此处添加的int结果将转换为char。为此,我们有两个变体,具体取决于char(实现定义)的签名:

  • unsigned:结果以标准定义的方式转换为unsigned char
  • signed:结果是以实现定义的方式“down-”转换为“较小的”signed char

所以:没有 未定义的行为,但是(以及评论)显示了在C中使用有符号整数时必须记住的程度。

<强>可是:

涉及太多实现定义的行为并且需要许多先决条件(尽管这很常见)。最好在整个代码中使用unsigned charunsigned int。这将使代码标准兼容并且表现良好。即使是CHAR_BIT以外的值。如果您依赖8位值,请使用uint8_t中的stdint.h