zlib は、sgcWebSockets に含まれる数少ないサードパーティ製 C コードのひとつです。WebSocket の permessage-deflate 拡張を支えているため、サーバーが送受信する圧縮フレームはすべて zlib を通過し、HTTP のコンテンツエンコーディングも zlib が処理します。sgcOpenAPI は同じソースを共有しているので、同じコピーを使用します。2026.8.0 より、そのコピーは zlib 1.2.12 から zlib 1.3.1 に移行します。
この変更は API からは見えません。お客様のコードに手を加える必要はなく、圧縮の動作も変わりません。説明しておく価値があるのは、小さな C ライブラリのバージョンアップがなぜ単なるファイルの差し替え以上の作業になるのか、そしてサポートするすべてのコンパイラで安全だと確信するために何を行ったか、という点です。
1.3.1 が修正する内容と、なぜ影響を受けていなかったのか
1.2.12 と 1.3.1 の間で最も注目される修正は CVE-2022-37434 で、inflate() におけるヒープの過剰読み取りです。これは、呼び出し側のアプリケーションが extra フィールドにバッファを指定した gz_header を zlib に渡した場合にのみ到達します。その場合 zlib は gzip の extra フィールドをそこへコピーしますが、1.2.12 ではそのコピーに境界チェックが欠けていました。
sgcWebSockets はその条件を満たすことがありません。inflateGetHeader はゼロ初期化された gz_header でのみ呼び出され、head.extra を代入することは一切ないため、該当する分岐には入れませんでした。私たちは対応を決める前にソースでこれを確認しており、はっきりと述べます。以前のバージョンでビルドされたアプリケーションは、この経路で脆弱ではありませんでした。
それでも更新しました。自動スキャナーやサプライヤー向けの質問票が読み取るのは呼び出しグラフではなくバージョン文字列であり、依存関係スキャンを実行しているお客様が指摘事項を解消するために私たちの論拠を再構成する必要はないはずです。アップグレードすれば、この議論を何度も繰り返す必要がなくなります。
zlib の更新がファイルの差し替えではない理由
zlib は DLL として配布されるのではなく実行ファイルにコンパイルされて組み込まれます。だからこそ sgcWebSockets アプリケーションの隣に zlib1.dll は存在しません。このリンクはあらかじめコンパイルされたオブジェクトファイルで行われ、Delphi はその形式に厳密です。したがって zlib の更新はそれらのオブジェクトの再ビルドを意味し、しかもセットはひとつではなく 3 つあります。
| 使用対象 | 形式 | ビルドに使用 |
|---|---|---|
| Delphi 7 から XE まで | OMF | bcc32、ZEXPORT=__fastcall |
| XE2 以降、Win32 | OMF | bcc32、ZEXPORT=__cdecl |
| XE2 以降、Win64 | COFF | MSVC cl |
2 つの 32 ビット向けセットは呼び出し規約が異なります。古いコンパイラは zlib を Delphi の register 規約でリンクするのに対し、XE2 以降は cdecl を使うためです。64 ビット向けのセットはさらにオブジェクト形式そのものが異なります。ここで注目すべきは bcc64 ではこれを生成できないという点です。bcc64 は ELF オブジェクトを出力する一方で Delphi の Win64 リンカーは COFF を要求するため、このセットは Microsoft のコンパイラでビルドされています。
これらはいずれもお客様からは見えません。zlib のバージョンアップがダウンロードではなくビルド作業になる理由、というだけのことです。
最新版だけでなく、すべてのコンパイラで検証
再ビルドしたオブジェクトは、正常にコンパイルできても誤っている可能性があるため、リンクテストだけでは不十分です。サポート対象のすべてのコンパイラで、バッファを圧縮し、展開し、バイト単位で比較したうえで、リンクされたオブジェクトが期待どおりのバージョンを報告することを検証するプログラムをビルドし、実際に実行しました。
uses
sgcIdCTypes, sgcIdGlobal, sgcIdZLibHeaders;
var
vPackedLen: TIdC_ULONG;
begin
vPackedLen := SizeOf(vPacked);
if compress(PIdAnsiChar(@vPacked[0]), vPackedLen,
PIdAnsiChar(@vSrc[0]), SizeOf(vSrc)) <> 0 then
raise Exception.Create('compress failed');
WriteLn('zlib ', String(AnsiString(zlibVersion))); // zlib 1.3.1
end;
これを Delphi 7、Delphi 2007、Delphi 2009、および RAD Studio XE6 から 13 まで、Win32 と、プラットフォームが存在する場合は Win64 でも実行しました。25 通りの組み合わせすべてが成功し、1.3.1 を報告しています。
途中で見つかり修正された潜在的な 64 ビットのバグ
このマトリクスによって、新バージョンとはまったく関係のない問題が見つかりました。Delphi 10 Seattle では、64 ビットビルドが 32 ビットのオブジェクトを選択しており、それは 64 ビット実行ファイルにリンクできないため Bad object file format エラーが発生していました。原因は Seattle 固有の問題を回避するために設けられた古い条件分岐で、その組み合わせだけを誤ったオブジェクトセットに振り分けていました。現在は Seattle の 64 ビットも他のすべての 64 ビットターゲットと同じオブジェクトを使用し、正常にコンパイルされます。
sgcOpenAPI も同じ更新を受け取ります
sgcOpenAPI は zlib を含めてソースを sgcWebSockets と共有しているため、同じリリースで 1.3.1 に移行します。お客様側で個別の作業は必要ありません。
必要な作業
2026.8.0 をインストールし、プロジェクトを再ビルドしてください。設定するプロパティも、追加や削除するユニットも、配布方法の変更もありません。zlib はもともと実行ファイルの中にあり、今もそのままだからです。自社製品のソフトウェア部品表を管理している場合は、zlib のエントリを 1.3.1 に更新すれば、記載していた CVE-2022-37434 の注記を削除できます。
