跨版本執行時保證
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.2 | 3.20.3 | 3.21.6 | 3.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。