クロスバージョン ランタイム保証
Protobuf の言語バインディングには2つのコンポーネントがあります。生成されたコード(通常は `protoc` から生成される)と、生成されたコードを使用する際に含める必要があるランタイムライブラリです。これらが異なるバージョンの Protobuf から来ている場合、私たちは「クロスバージョンランタイム」の状況にあります。
ほとんどの言語において、以下の保証を提供することを意図しています。これらはデフォルトの保証ですが、Protobuf コードジェネレーターおよびランタイムの所有者は、その言語に特化したより厳密な保証で明示的にこれらを上書きすることができます。C++ と Rust は通常よりも厳しい保証を持ち、Python は緩い保証を持ちます。
保証外のProtobufクロスバージョン利用は、エラーを起こしやすく、サポートされていません。バージョンずれは、ソース互換性のある変更がない限り問題なく動作するように見えることが多いとしても、診断が難しい不安定な動作や未定義の動作につながる可能性があります。Protobufの場合、サポートされていないProtobuf言語バインディングの使用に依存するツールやサービスが多いため、Protobufチームはバグレポートやセキュリティ脆弱性に対応してProtobufの実装を更新することができません。
新しい生成コード + 古いランタイム = 許可されない
新しいランタイムAPIは、いかなる種類のリリース(メジャー、マイナー、パッチ)でも追加される可能性があります。そのリリースで生成されたコードは、これらの新しいAPIを使用することが許可されます。その結果、生成されたコードは、それらのバインディングを生成するために使用された`protoc`とプラグインよりも古いランタイムと組み合わせるべきではありません。
新しい生成コードを古いランタイムと組み合わせようとする試みを防ぐため、可能な限り「ポイズンピル」を追加します。
メジャーバージョン
2025年第1四半期のリリースから、Protobuf プロジェクトはメジャーバージョンに対してローリング互換性ウィンドウを採用します。メジャーバージョン V (完全なバージョン: V.x.y) 用に生成されたコードは、バージョン V および V+1 の Protobuf ランタイムによってサポートされます。
このポリシー以前は、3.22.x+ (メジャーバージョン4の約1年前にリリース) 用に生成されたコードは、バージョン3および4のProtobufランタイムによって引き続きサポートされます。古い生成コードを持つユーザーは、3.25.xの最新の生成コードにアップグレードする必要があります。
Protobufは、バージョンVの生成コードをランタイム>=V+2で使用することをサポートせず、ソフトウェアアセンブリがそのような構成を使用しようとすると、明確なエラーメッセージを表示して失敗する「ポイズンピル」メカニズムを使用します。
注: C++ と Rust は互換性ウィンドウをサポートせず、Python ははるかに長い期間をサポートします。
マイナーバージョン
単一のメジャーランタイムバージョン内では、古いバージョンの`protoc`で生成されたコードは、新しいランタイム上で実行されます。
注: C++ と Rust はマイナーバージョン間の互換性をサポートしていません。
セキュリティ例外
セキュリティ上の理由で必要と判断された場合、上記の約束を破る権利を留保します。これらの例外は稀であると予想されますが、常にこれらの保証よりもセキュリティを優先します。例えば、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安定性を保証しません。
Python 固有の保証
3.20.0リリース以降、Protobuf Pythonで生成されたコードは、埋め込みのFileDescriptorProto
の薄いラッパーとなりました。これらのプロトは非常に長い期間にわたってサポートされているため、通常のメジャーバージョン互換性ウィンドウは通常必要ありません。
Pythonは将来の特定のメジャーバージョンリリースで生成コードの互換性を破る可能性がありますが、それは事前にポイズンピルの警告とエラーを伴います。6.32.0現在、3.20.0以降に生成されたすべてのコードは、少なくとも8.x.yまでサポートされます。