テクノロジー · 実用ガイド
zlibがeofでも回り続ける?保留入力と次のgzipメンバーを分ける
28項目のローカル検証で、終了後の末尾再投入、最初のメンバーだけの出力、全文が出ても未完了な第2メンバーを区別しました。

解凍オブジェクトがeof=Trueでも、gzip入力に次のメンバーが残っていることがあります。実際のCPython 3.12.14ではeof後にもunconsumed_tailが残り、それを終了済みの同じオブジェクトへ戻すと、新しい出力なしにunused_dataへ末尾が繰り返し追加されました。
一つのメンバー終了後もループする問題と、早く停止して次を欠落させる問題は別です。28個の小さな対照では、第2メンバーが切れていても合計9バイトの期待する平文すべてが出る一方、そのeofはFalseのままという例も確認しました。
1. 出力長だけでなくオブジェクト状態を記録
sys.version、zlib.ZLIB_VERSION、zlib.ZLIB_RUNTIME_VERSION、wbits、単一/複数メンバーの許可方針を記録します。実測はCPython 3.12.14/Linux、ビルド時と実行時のzlibはともに1.3.2でした。参照したCライブラリ上流マニュアルは1.3.1であり、実行版と混同していません。
小さな診断呼び出しごとに、出力長、eof、unconsumed_tailとunused_dataの長さを記録します。eof前はmax_lengthで出力が制限され、保留入力の再処理が必要な場合があります。eof後は形式方針に従って末尾を扱い、二つの属性を無条件に同じオブジェクトへ戻さないでください。
2. 終了したオブジェクトへの再投入を止める
zlib形式のテストは1024バイトの平文と5バイトの接尾辞extraを含みます。1回100バイトを上限とし、not d.eof and d.unconsumed_tailの間だけ続けると正しい全ペイロードが得られました。実行した版では完了時に両方の末尾属性がextraを含み、独立した二つの断片として足すべきではありませんでした。
その後、保留末尾を使って明示的に3回だけ追加呼び出しをしました。新しい出力はすべてゼロで、unused_dataは5から20バイトへ増え、unconsumed_tailは5のままでした。無限ループは実行していません。上流課題はeof条件を示し、修正へのリンク付きで終了しています。全現行Pythonの未修正問題とはせず、導入版で確認してください。
3. メンバー終了は入力全体の成功ではない
49バイトのgzipテストはalphaを含む25バイトのメンバーとbetaを含む24バイトのメンバーを連結しました。一つのzlib.decompressobj(31)はalphaだけを返し、eof=True、unused_dataに正確な24バイトの次メンバーを保持しました。この出力無制限呼び出しではunconsumed_tailは空でした。
unused_dataを新しいオブジェクトへ渡すとbetaが得られ、eofに達して接尾辞は残りませんでした。小さな完全テストへのgzip.decompressは文書通りalphabetaを返しました。これらのAPIやコミュニティの新オブジェクト手順は既知です。大きい外部入力には必要な方針と制限を備えた保守されるリーダーを選び、このメモリ内比較を運用設計と見なさないでください。
4. 空出力や期待する平文を完了判定にしない
有効な空gzipメンバーは平文を出しませんがeofに達し、次メンバーを残します。空出力を入力全体の終わりとするループは、有効な後続データを落とす可能性があります。最新出力の有無だけでなく、メンバー完了と保留入力を追跡します。
第2メンバーのトレーラーから4バイトを削除しても、二つのオブジェクトはalphabetaの期待する9バイトをすべて出しましたが、第2のeofはFalseでした。flush()も欠けたトレーラーの完了を証明しません。第2CRCを壊した別対照でも第1はalphaを返し、第2メンバーを処理して初めてエラーが発生しました。
5. 受け入れるメンバーの方針を決める
単一の完全メンバーだけ許可し、残りをすべて拒否するプロトコルもあります。複数を許可し各メンバーに新しいデコーダーを使うものもあります。unused_dataを黙って捨てたり、任意の接尾辞を有効メンバーと仮定したり、重複し得るunconsumed_tailと足したりしないでください。garbageという接尾辞は新gzipとしての処理に失敗しました。
出力予算は全メンバーで合計し、実際のリーダーに応じて入力、メンバー数、時間、上流バッファも制御します。max_lengthは1回の出力を制限し、ゼロは無制限です。flush(length)は初期バッファサイズで上限ではありません。実験ではmax_length=0で1024バイト、1で1バイトでした。プロセスメモリ、CPU制限、ネットワーククライアントは測っていません。
6. 完了検査が保証する結果だけを確定する
回帰診断には小さな既知の入力を使います。有効1メンバー、有効2メンバー、空の第1メンバー、第2トレーラー切断、第2CRC破損、非メンバー接尾辞を調べます。正確な出力、受理した各メンバーの完了、最終末尾方針を確認し、便利な接頭辞を完全な結果として確定しないでください。
28断言すべてが記載の環境で通過しました。報告には版、プラットフォーム、スクリプトSHA、実際の状態を保存しています。汎用ストリーミングリーダーの実装や修正版の実行、HTTP完結性、真正性、資源安全性の検証ではありません。正しいメンバー遷移は必要条件であり、受理入力全体の完了はアプリケーションが定義します。
