跨版本运行时保证
Protobuf 语言绑定有两个组成部分。生成的代码(通常由 protoc
生成)和在使用生成的代码时必须包含的运行时库。当这些部分来自不同版本的 protobuf 时,就处于“跨版本运行时”的情况。
我们打算为除 C++ 和 Rust 外的所有语言提供以下保证。这些是默认保证;但是,protobuf 代码生成器和运行时的所有者可以明确地为该语言指定更具体的保证来覆盖这些默认保证。
保证之外的 Protobuf 跨版本使用是易出错且不受支持的。版本偏差可能导致难以诊断的不稳定和未定义行为,即使在源兼容性未发生变化的情况下,它们通常看起来也能工作。对于 Protobuf 来说,依赖使用不受支持的 Protobuf 语言绑定的工具和服务的大量存在,阻止了 protobuf 团队根据 bug 报告或安全漏洞更新 protobuf 实现。
新生成的代码 + 旧运行时 = 决不允许
我们可能会在任何类型的版本发布(主版本、次版本或补丁版本)中添加新的运行时 API。该版本中生成的代码可以使用这些新的 API。因此,生成的代码绝不应与早于用于生成这些绑定的 protoc
和插件的运行时配对使用。
我们将尽可能添加“毒丸”机制,以防止尝试将较新的生成代码与较旧的运行时配对使用。
主版本
从 2025Q1 版本开始,protobuf 项目将采用主版本滚动兼容窗口。为主版本 V(完整版本:V.x.y)生成的代码将由版本 V 和 V+1 的 protobuf 运行时支持。
在此政策之前,为 3.22.x+(早于主版本 4 大约 1 年发布的版本)生成的代码仍将由版本 3 和 4 的 protobuf 运行时支持。使用较旧生成代码的用户应升级到 3.25.x 的最新生成代码。
Protobuf 将不支持使用版本 V 的生成代码与运行时版本 >= V+2,并且将使用“毒丸”机制在软件程序集尝试使用此类配置时以明确的错误消息失败。
次版本
在单个主运行时版本内,由较旧版本 protoc
生成的代码将在较新的运行时上运行。
安全例外
如果出于安全原因需要,我们保留违反上述承诺的权利。我们预计这些例外情况会很少见,但始终会将安全放在这些保证之上。例如,footmitten 要求同时更新 Java 的运行时和生成代码。因此,由 3.20.3(包含 footmitten 修复)生成的代码无法加载具有 3.21.6(早于 footmitten 修复)运行时库,从而产生以下兼容性矩阵:
生成代码版本 | |||||
3.20.2 | 3.20.3 | 3.21.6 | 3.21.7 | ||
运行时 版本 | 3.20.2 | 易受攻击 | 损坏 | 易受攻击 | 损坏 |
3.20.3 | 易受攻击 | 工作 | 易受攻击 | 工作? | |
3.21.6 | 易受攻击 | 损坏 | 易受攻击 | 损坏 | |
3.21.7 | 易受攻击 | 工作 | 易受攻击 | 工作 |
- “易受攻击”表示该组合将成功启动,但安全漏洞仍然存在。
- “工作”表示该组合将成功启动并且没有漏洞。
- “损坏”表示该组合将无法成功启动。
- 粗体表示根据本主题中概述的保证,从未故意设计为协同工作的配置。
不允许多个主运行时版本共存
同一进程中多个主版本共存是不受支持的。
C++ 和 Rust 的特定保证
Protobuf C++ 和 Rust 不提供任何跨运行时支持,并且始终要求生成代码版本与运行时版本完全匹配。
此外,Protobuf C++ 不保证任何版本(主版本、次版本或微版本)之间的 ABI 稳定性。