字符串错误检查

时间:2015-10-01 13:48:49

标签: c++ string error-handling

我在我的代码中使用了许多字符串函数,如 strncpy strncat sprintf 等。我知道有更好的替代方案,但我被交给了一个旧项目,使用了这些功能,因此我必须坚持使用它们以实现兼容性和一致性。我的主管非常挑剔错误检查和健壮性,并坚持每次使用这些功能时都会检查缓冲区溢出违规。这在我的代码中创建了很多if-else语句,看起来不太漂亮。我的问题是,每次调用其中一个函数时,是否真的有必要检查溢出?即使我知道可能发生缓冲区溢出,例如使用sprintf函数在字符串中存储整数时

sprintf(buf,"%d",someInteger);

我知道64位系统上无符号整数的最大长度可以是20位。另一方面, buf 长度超过20个字符。在这种情况下我还应该检查缓冲区溢出吗?

4 个答案:

答案 0 :(得分:1)

也许编写一个可以调用的测试用例来简单地测试缓冲区以减少代码重复和丑陋。

您可以将if / else语句抽象为另一个类的方法,然后传入预期的缓冲区和长度。

本质上,这些缓冲区非常容易被覆盖,因此请注意从用户/外部源获取输入。您还可以尝试获取字符串长度(使用strlen),或者自己检查/ 0结束字符串字符,并将其与缓冲区大小进行比较。如果循环使用/ 0字符,并且它不在那里,如果不按预期的缓冲区大小限制循环的最大大小,则会进入无限循环,因此也要检查它。

另一种选择是重构代码,这样每次使用这些方法时,都要用你编写的长度安全版本替换它们,在那里调用已经存在这些检查的方法(但必须传递缓冲区大小)它)。对于某些项目而言,这可能是不可能的,因为单元测试的复杂性可能非常难。

答案 1 :(得分:1)

我认为可行的方法是使用例外。如果必须解耦程序的正常控制流和错误检查,则异常非常有用。

您可以做的是为每个字符串函数创建一个包装器,在其中执行错误检查并在发生缓冲区溢出时抛出异常。

然后,在您的客户端代码中,您只需在try块内调用包装器,然后检查异常并在catch块内返回错误代码。

示例代码(未经测试):

int sprintf_wrapper( char *buffer, int buffer_size, const char *format, ... )
{
    if( /* check for buffer overflow */ )
        throw my_buffer_exception;

    va_list  arg_ptr;
    va_start( arg_ptr, format );
    int ret = sprintf( buffer, , format, arg_ptr );
    va_end(arg_ptr);
    return ret;
}

Error foo()
{
    //...
    try{
        sprintf_wrapper(buf1, 100, "%d", i1);
        sprintf_wrapper(buf2, 100, "%d", i2);
        sprintf_wrapper(buf3, 100, "%d", i3);
    }
    catch( my_buffer_exception& )
    {
        return err_code;
    }
}

答案 2 :(得分:1)

让我先解决你的最后一段:你编写一次代码,而不是维护和使用它的时间。猜猜您认为您的代码将被使用多长时间,然后将其乘以10-20以确定实际正在使用多长时间。在那个窗口的末尾,完全可能是一个整数可能更大并且溢出你的缓冲区,所以是的,你必须做缓冲区检查。

鉴于您有几个选择:

  • 使用“{n”系列函数(如snprintf)来防止缓冲区溢出,并告诉用户未定义缓冲区溢出时会发生什么。

  • 当发生长度违规时,请将其视为致命的abort()或抛出未捕获的异常。

  • 尝试通知用户存在问题,并中止操作或尝试让用户修改输入并重试。

前两种方法肯定会更容易实现和维护,因为您不必担心以合理的方式将正确的信息反馈给用户。在任何情况下,你很可能会像其他答案中所建议的那样考虑到函数。

最后让我说,既然你已经标记了这个问题C ++而不是C,那就慢慢思考将代码库慢慢迁移到C ++(因为你的代码库现在是 C)并利用然后C ++工具完全不需要这些缓冲区检查,因为它会自动发生。

答案 3 :(得分:0)

您可以使用gcc " -D_FORTIFY_SOURCE = 1 D_FORTIFY_SOURCE = 2" 进行缓冲区溢出检测。

https://securityblog.redhat.com/2014/03/26/fortify-and-you/