DOCX と EPUB を処理する前に、ZIP 解凍の予算を設定します
DOCX は本質的に ZIP エントリのセットであり、EPUB も ZIP コンテナを使用します。非常に小さい圧縮ファイルを受け取ったからといって、それを解凍した後もさらに小さいとは限りません。ファイルが異常であると判断する前にメモリが不足するのを待つのではなく、圧縮ボリューム、エントリ数、個々のアイテムのサイズ、および合計展開量をエントリ ポイントで制限する必要があります。
DOCX と EPUB を扱う場合、解凍段階ですでに多くの問題が発生します。 DOCX は本質的に ZIP エントリのセットであり、EPUB も ZIP コンテナを使用するため、ファイル サイズが小さいからといって解凍後のサイズが小さくなるわけではありません。この記事は、Office ドキュメントまたは電子ブックを受け取り、その後の処理を実行する必要がある開発者および運用保守担当者を対象としています。入り口でZIP解凍の予算を設定する方法を紹介します。
これを読むと、入り口にどの制限を設定する必要があるか、実用的な拒否情報をユーザーに返す方法、および翻訳が失敗した場合にコンテナの問題と翻訳の問題を区別する方法を決定できます。この記事の例は合成サンプルを使用して実証されており、コードは隔離された環境でのサンプル チェックに合格していますが、これはすべての実際のファイルに対して有効であることを意味するものではありません。重要な書類を処理する前に、原本を保管し、本文の境界と許容事項に従って確認してください。
DOCX と EPUB を処理する前に ZIP 解凍の予算を設定するにはどうすればよいですか?一文の結論
圧縮ボリューム、エントリ数、個々のアイテムのサイズ、および合計展開量は、エントリ ポイントで制限される必要があります。ファイルの異常を発見する前に、メモリが使い果たされるまで待たないでください。
| あなたの状況 | 推奨される実践方法 | 理由 |
|---|---|---|
| DOCXまたはEPUB圧縮ファイルを受信 | 圧縮ボリューム、エントリ数、個々のアイテムのサイズ、入口での総展開量を制限する | 圧縮パッケージのサイズが小さいからといって、解凍後のサイズが小さくなるわけではありません。 |
| カタログだけで事前審査をしたい。 | ディレクトリ テーブルは、解凍中に読み取られたバイトを蓄積しながら、早期に拒否するために使用されます。 | カタログ テーブルは実行時制約の代わりにはなりません |
| かなり大きなドキュメントが予算を超えている | 独立した大規模ファイルキューまたは手動処理入口を提供する | 合理的な文書も予算を超える可能性がありますが、すべての制限を取り除くべきではありません |
| 翻訳に失敗しました | まずコンテナの損傷と翻訳の失敗を区別します | 問題は入力準備段階にある可能性があります |
最初に拡張サイズを確認する必要があるのはなぜですか?
DOCX と EPUB はどちらも ZIP をコンテナとして使用します。数百 KB のファイルは、解凍後に大量のスペースを占有する場合があります。システムがアップロードされたファイルのサイズのみを確認する場合、この種のリスクを検出することはできません。
したがって、入り口での検査は次の側面を同時にカバーする必要があります。
- 圧縮ボリューム: アップロードされるファイル自体のサイズを制限します。
- エントリ数: コンテナ内のファイル数を制限します。
- 単一アイテムのサイズ: 1 つのアイテムの拡張サイズを制限します。
- 合計拡張: すべてのエントリの拡張後の合計バイト数を制限します。
最初に目次を確認してください。ただし、それを最終的な保証として受け取らないでください。
ZipInfo は、事前スクリーニングに適した宣言サイズと圧縮サイズを提供します。これにより、明らかに予算を超えたファイルをシステムが解凍前に迅速に拒否することができます。
ただし、ディレクトリ テーブル内の情報はファイル自体によって宣言されているため、完全に信頼できるわけではありません。実際に解凍するときは、読み取られたバイトを蓄積し、時間とメモリ バジェットを設定する必要があります。カタログ テーブルはファイルを早期に拒否できますが、実行時の制限を置き換えることはできません。
解凍を行わないプレスクリーニングの例
from io import BytesIO
from pathlib import PurePosixPath
from zipfile import ZipFile, ZIP_DEFLATED
def inspect(raw, max_entries=10, max_total=4096):
if len(raw) > 4096:
raise ValueError("compressed input budget")
with ZipFile(BytesIO(raw)) as z:
items = z.infolist()
if len(items) > max_entries:
raise ValueError("entry count budget")
total, seen = 0, set()
for item in items:
name = item.filename
path = PurePosixPath(name)
if (path.is_absolute() or ".." in path.parts or
"\\" in name or ":" in name or name in seen):
raise ValueError("unsafe or duplicate name")
seen.add(name)
total += item.file_size
if total > max_total:
raise ValueError("expanded budget")
return len(items), total
def sample(name, data):
out = BytesIO()
with ZipFile(out, "w", ZIP_DEFLATED) as z:
z.writestr(name, data)
return out.getvalue()
assert inspect(sample("word/document.xml", b"<doc/>")) == (1, 6)
for raw in [sample("../escape", b"x"), sample("large", b"x" * 5000)]:
try:
inspect(raw)
except ValueError:
pass
else:
raise AssertionError("unsafe archive accepted")
この例のバジェットは、拒否パスを示すために選択された小さな値であり、運用環境で直接複製することはできません。この例では extractall を呼び出したり、ZIP エントリを書き込んだりしないため、完全に安全な解凍プログラムではありません。
暗号化されたエントリ、シンボリック リンク、ネストされたアーカイブ、およびパーサー自体のリソース消費にはすべて個別のポリシーが必要です。
参考:Python zipfile。
拒否する場合は、ユーザーに実用的な情報を提供します
ユーザーは、ファイルが拒否された場合に次に何をすべきかを知っておく必要があります。十分なトラブルシューティング情報を内部的に記録する必要があります。次の表に、一般的なトリガー条件に対応する処理メソッドを示します。
| トリガー条件 | ユーザー向けの説明 | 内部記録 |
|---|---|---|
| 総拡張が予算を超える | 展開するとファイルが大きすぎます | 名前と観察を制限する |
| 重複記事タイトル | コンテナ構造は不明です | エントリーインデックス、全文記録なし |
| 国境を越える道 | ファイル構造はサポートされていません | セキュリティインシデント関連ID |
| コンテナ損傷 | ファイルを再エクスポートしてください | 例外の構文タイプ |
ユーザーへの説明は簡潔かつ明確にし、内部の詳細を過度に露わにしないようにします。 内部記録には、制限名、観測値、異常タイプを保持し、その後のトラブルシューティングを容易にする必要があります。
相性のためにすべての制限を閉ざさないでください
比較的大きな文書は予算を超えることもあります。 現時点では、すべてのタスク制限を緩和するのではなく、独立した大きなファイルキューや手動処理のエントリーポイントを提供することが賢明なアプローチです。
テナントのビジネスクォータを増やすことは、すべてのタスクを無制限に解凍させることを意味しません。 制限は実行から切り離す必要があり、アップロードボタンの横にだけ書くことはできません。
どの層の翻訳障害がどの層にあるかを区別する
OmniDoc(製品エントリー)への文書提出準備をする際は、まずコンテナ破損と翻訳失敗を区別してください。 XMLすら読めないDOCXは入力準備段階で問題が起きることがあります。 明確な事前検査レポートは、再エクスポート、画像圧縮、またはトラブルシューティングのために翻訳サービスに連絡すべきかをユーザーに示します。
📊 コア比較
| タイミングを確認して | 主な機能 | 制限 |
|---|---|---|
抽出前にディレクトリテーブルを確認してください(ZipInfo) | 宣言されたサイズと圧縮サイズに基づいて事前スクリーニングを行い、明らかに制限を超えるファイルは事前に拒否します | 宣言情報はファイル自体から得られ、実行時の制限を置き換えることはできません |
| 抽出時に読み取ったバイトを蓄積します | 実際の展開を管理するために時間とメモリバジェットを調整する | 読み上げ過程では連続的なカウントが必要です |
🎯 どの方法があなたに合いますか?
ユーザーがアップロードしたDOCXやEPUBを受け取る必要がある場合は、
入口地点では、圧縮体、エントリ数、個別アイテムサイズ、総膨張度を同時に確認してから次の処理に進みます。
もし主に目次に頼って確認するなら、
ディレクトリテーブルをプリエンプティブリジェクションメソッドとして使い、同時に実際の抽出時に読み取ったバイトを蓄積し、時間とメモリの予算を設定します。
かなり大きな文書に頻繁に出会うなら
これらの文書に対して独立した大きなファイルキューや手動処理のエントリポイントを提供し、互換性のためだけにすべての制限を無効にしないでください。
OmniDocに書類を提出する準備ができたら
まず、コンテナ損傷と翻訳失敗を区別しましょう。 事前検査段階で発見された問題は、できるだけ早くユーザーに報告できます。
❓ よくある質問(FAQ)
1. ディレクトリテーブルのサイズを直接ファイルセキュリティの判断に使うことはできますか?
完全に頼ることはできません。 ZipInfoが提供する宣言サイズは事前スクリーニングに適していますが、実際の抽出には読み取りバイトの蓄積や時間・メモリバジェットの設定が必要です。
2. なぜ圧縮パッケージはこんなに小さいのに、開封するとかなり大きくなってしまうのでしょうか?
DOCXもEPUBもZIPをコンテナとして使用しています。圧縮パッケージが小さいからといって、拡張後のサイズも小さいわけではありません。 したがって、総展開量を制限する必要があります。
3. 予算を超える大規模な文書はどのように扱うべきでしょうか?
比較的大きな文書は予算を超えることもあり、すべての制限を閉じる代わりに、別々の大きなファイルキューや手動処理のエントリーポイントを提供します。
4. 翻訳が失敗したとき、問題の所在をどうやって見極めますか?
まず、コンテナ損傷と翻訳失敗を区別しましょう。 XMLすら読み取れないDOCXは、入力準備段階で問題が起こることがあります。明確な事前チェックレポートは、再エクスポート、画像圧縮、またはトラブルシューティングのために翻訳サービスに連絡するかどうかをユーザーが判断するのに役立ちます。
📝 概要
エントリでのZIP減圧制限は、圧縮容量、エントリ数、個別アイテムサイズ、総拡張量を同時にカバーし、実行中の累積チェックも含めるべきです。 拒否時に次のステップを明確に示すことで、問題の解決が容易になります。


