先决条件和后置条件¶
安全编码的重要组成部分是确保不正确的数据不会在代码中传播太远——恶意输入传播得越远,它看到的代码就越多,漏洞的可能性就越大。
防止无效数据传播的标准方法是检查库或模块中所有公开可见函数的输入和输出。 有两种级别的检查
- 验证
检查无效输入,并在失败时优雅地返回错误。
- 断言
检查程序员错误,并在失败时中止程序。
验证¶
验证是一个复杂的主题,通常使用 GError 处理。 有关如何在 API 中使用 GError 的更多信息,请参阅 GLib 关于错误报告的参考。
本节的其余部分讨论先决条件和后置条件断言,这些断言完全用于捕获程序员错误。 程序员错误是指以文档中禁止的方式调用函数。 例如,如果将 NULL 传递给参数,而该参数的文档规定需要传递非 NULL 值;或者,如果将负值传递给需要正值的函数。 程序员错误也可能发生在输出端——例如,在未记录返回 NULL 时返回 NULL,或者在失败时未设置 GError 输出。
断言¶
将先决条件和后置条件断言添加到代码中,与添加断言本身一样,重要的是要确保正确且完整地记录每个函数的行为。 所有断言都应记录在案,最好使用相关的 内省注解,例如 (nullable)。
先决条件和后置条件断言使用 g_return_if_fail() 和 g_return_val_if_fail() 实现。
先决条件应在函数开始时检查每个参数,在执行任何其他代码之前(例如,即使是从 GObject 中检索私有数据结构,因为 GObject 指针可能为 NULL)。 后置条件应在函数结束时检查返回值和任何输出参数——这需要一个 return 语句,并使用 goto 将其他控制路径合并到其中。 请参阅 单路径清理 以获取示例。