跨版本執行時保證

該語言在跨版本執行時相容性方面的保證。

Protobuf 語言繫結有兩個元件。生成程式碼(gencode)和實現該生成程式碼通用功能的執行時庫。當它們來自不同版本的 protobuf 時,我們就處於“跨版本執行時”情況。

我們打算對大多數語言提供以下保證。這些是預設保證;但是,protobuf 程式碼生成器和執行時的所有者可以為該語言明確覆蓋它們,提供更具體的保證。C++ 和 Rust 具有比典型情況更嚴格的保證,而Python 則更寬鬆。

不在保證範圍內的 Protobuf 跨版本使用是易出錯且不受支援的。版本錯配可能導致難以診斷的錯誤和未定義的行為,即使它通常似乎有效,只要原始碼不相容的地方沒有改變。對於 Protobuf 來說,依賴使用不受支援的 Protobuf 語言繫結的工具和服務的泛濫,使得 protobuf 團隊無法響應錯誤報告或安全漏洞來更新 protobuf 實現。

新生成的程式碼 + 舊執行時 = 絕不允許

我們可能會在任何型別的版本(主版本、次版本或補丁版本)中新增新的執行時 API。該版本中的 gencode 被允許使用這些新 API。其結果是,gencode 永遠不應與用於生成這些繫結的 protoc 和外掛早於的版本進行配對。

我們將在可能的情況下新增“毒丸”(poison pills)以阻止將較新的 gencode 與較舊的執行時配對的嘗試。

主版本

Protobuf 對主版本實現了滑動視窗相容性。為主要版本 V(完整版本:V.x.y)生成的程式碼將得到主要版本 V 和 V+1 的 protobuf 執行時的支援。

Protobuf支援將版本 V 的 gencode 與執行時 >= V+2 一起使用,並將使用“毒丸”機制,在軟體元件嘗試使用此類配置時會以清晰的錯誤訊息失敗。

例如

  • 由 protobuf 版本 3.0.0 生成的 Java 程式碼將與 3.0.0 到 4.x.y 的執行時一起工作,但與 2.0.0 到 2.x.y 的執行時或 >= 5.0.0 的執行時一起工作。
  • 由 protobuf 版本 4.27.2 生成的 Java 程式碼將與 4.27.2 到 5.x.y 的執行時一起工作,但與 2.0.0 到 4.27.1 的執行時或 >= 6.0.0 的執行時一起工作。

當無法維護與舊 gencode 的相容性時,可能會做出例外,例如在需要更新 gencode 的安全修復時。

注意:毒丸是在 protobuf 26.0 版本中引入的。早於 4.26.0 的 Java gencode 可能看起來與比 gencode 舊的執行時一起工作。然而,較新的 gencode 和較舊的執行時的組合可能存在嚴重的錯誤,這些錯誤直到執行時才會顯現。

注意:C++ 和 Rust 不支援相容視窗,而Python 支援更長的相容視窗。

次版本

在單個主執行時版本內,來自較舊 protoc 版本的生成程式碼將在較新的執行時上執行。

注意:C++ 和 Rust 不支援次版本之間的相容性。

安全例外

我們保留因安全原因而違反上述承諾的權利。我們預計這些例外情況將很少見,但始終會將安全性置於這些保證之上。例如,footmitten CVE 要求 Java 的執行時和生成程式碼進行配對更新。因此,由 3.20.3(包含 footmitten 修復)生成的程式碼將無法載入與執行時庫 3.21.6(在 footmitten 修復之前)一起使用,從而建立了以下相容性矩陣:

生成程式碼版本
3.20.23.20.33.21.63.21.7
執行時
版本
3.20.2漏洞!損壞!!有漏洞!!損壞!
3.20.3漏洞正常工作!有漏洞!!也許能工作?!
3.21.6漏洞損壞漏洞!損壞!
3.21.7漏洞正常工作漏洞正常工作
  • “有漏洞”(Vuln)表示組合將成功啟動,但安全漏洞仍然存在。
  • “正常工作”(Works)表示組合將成功啟動且沒有漏洞。
  • “損壞”(Broken)表示組合將無法成功啟動。
  • !粗體!表示混合了較新 gencode 和較舊執行時的配置,這些配置從未打算一起工作。

不允許多個主執行時版本共存

在同一程序中允許多個主版本共存是不受支援的。

C++ 和 Rust 特定保證

Protobuf C++ 和 Rust 放棄所有跨執行時支援,並始終要求生成程式碼版本與執行時版本精確匹配。

此外,Protobuf C++ 不保證任何版本(主版本、次版本或微版本)之間的 ABI 穩定性。

Python 特定保證

自 3.20.0 版本起,Protobuf Python 生成程式碼已成為嵌入式 FileDescriptorProto 的薄包裝器。由於這些 proto 的支援時間非常長,因此我們通常的主版本相容性視窗通常不是必需的。

Python 可能會在未來的特定主版本釋出中破壞生成程式碼的相容性,但會提前伴隨毒丸警告和錯誤。截至 6.32.0,自 3.20.0 以來的所有生成程式碼將至少支援到 8.x.y。