我们都知道 SQLite 是用 C 语言编写的, C 语言是一个内存不安全的编程语言, 这意味着你必须自己处理内存泄露,数组溢出等问题, 那么为什么 SQLite 不使用内存安全的语言,比如 Rust 呢?
SQLite 作者对这个问题进行了回答, 翻译如下:
最近,人们对Rust或Go等“安全”编程语言非常感兴趣,在这些语言中,不可能或至少很难犯内存泄漏或数组溢出等常见编程错误。因此,经常会出现一个问题,为什么SQLite没有用“安全”语言编码。
1. 在SQLite存在的头10年里,没有一种安全的编程语言。SQLite可以在Go或Rust中重新编码,但这样做可能会引入比修复的要多得多的错误,而且似乎还可能导致代码变慢。
2. 安全编程语言解决了简单的问题:内存泄漏、免费使用错误、数组溢出等。安全语言除了普通的C代码外,在解决计算SQL语句正确答案的更困难的问题方面没有其他帮助。
3. 安全语言经常被吹捧为有助于防止安全漏洞。足够正确,但SQLite不是一个特别安全敏感的库。如果应用程序运行的是不受信任和未经验证的SQL,那么它已经存在更大的安全问题(SQL注入),任何“安全”语言都无法解决。
诚然,应用程序有时会从不受信任的来源导入完整的二进制SQLite数据库文件,此类导入可能会呈现可能的攻击矢量。然而,SQLite中的这些代码路径是有限的,并且经过了非常好的测试。预验证例程适用于希望读取不受信任数据库的应用程序,这些数据库可以帮助在使用前检测可能的攻击。
4. 一些“安全”语言(例如:Go)不喜欢使用断言()。但使用断言()是保持SQLite可维护性的重要组成部分。就SQLite的开发人员而言,Go中缺乏断言()是一个展示阻止因素。有关更多信息,请参阅SQLite文章中的断言()的使用。
5. 安全语言插入其他机器分支,以验证数组访问是否在入站。在正确的代码中,这些分支永远不会被占用。这意味着机器代码不能100%进行分支测试,这是SQLite质量策略的重要组成部分。
6. 安全语言如果遇到内存外(OOM)情况,通常希望中止。SQLite旨在优雅地从OOM中恢复。目前还不清楚如何在当前的安全语言中做到这一点。
7. 所有现有的安全语言都是新的。SQLite的开发人员赞扬计算机语言研究人员努力开发更易于安全编程的语言。我们鼓励这些努力继续下去。在实现SQLite时,我们自己对旧的无聊语言更感兴趣。
尽管如此,有朝一日SQLite可能会在Rust中重新编码。在Go中重新编码SQLite不太可能,因为Go讨厌断言()。但 Rust 是一种可能性。在Rust中重新编码SQLite之前必须出现的一些先决条件包括:
1. Rust 需要多成熟一点,停止如此快速的变化,并进一步走向衰老和无聊。
2. Rust需要证明它可用于创建可以从所有其他编程语言调用的通用库。
3. Rust需要证明它可以生成适用于晦涩嵌入式设备的对象代码,包括缺乏操作系统的设备。
4. Rust需要拿起必要的工具,使一个人能够对编译的二进制文件进行100%的分支覆盖测试。
5. Rust需要一个机制来优雅地从OOM错误中恢复。
6. Rust需要证明它可以像C在SQLite中所做的那样工作,而不会造成重大速度损失。
如果您是“Rust狂热粉丝”,并认为Rust已经满足上述先决条件,并且SQLite应在Rust中重新编码,那么欢迎并鼓励您私下联系SQLite开发人员并争论您的案例。