Еще попиарюсь )) Мой топик 2009 г. на форуме http://forum.ixbt.com/topic.cgi?id=26:39721 по поводу сабжа.
Думаю, его уже достали этим вопросом разработчики архиваторов.
Спасибо всем. Тема закрыта.
Andrey Radchenko написано 29.07.2009 17:24 | |
Пишу тут одну утилитку для чтения zip. Но, имхо, нашел изъян в формате самого зип архива.
Напомню формат зипа, для тех, кто забыл 1. Вначале идут сжатые файлы с заголовками, в которых указана инфа по файлу (имя, размер и т.д.). 2. Затем идет, так называемый, центральный каталог, в котором фактически дублируется информация из заголовоков файлов. 3. И в самом конце идет завершающая запись центрального каталога, в которой указывается позиция в файле где начинается центральный каталог. Каждая из этих структур имеет 4-хбайтовую подпись. Но нет никаких гарантий, эти самые 4 байта не встретятся в ужатых данных, комментариях или еще где-либо. НО! Если сжатие идет в stdout (т.е. потоковое), то в заголовках файлов не указана длина ужатых данных. Длина, в таком случае, указывается ПОСЛЕ сжатых данных, где она уже бесполезна, т.к. чтобы узнать где находится эта длина, надо заранее знать сколько пропустить байтов т.е. знать эту самую длину. Еще копия длины данных находится в каталоге. Т.е. логичнее всего читать ее именно оттуда. НО! После завершающей записи центрального каталога может находится комментарий. Причем длина этого комментария указана до самого комментария. Т.е. чтобы определить где находится заверш. запись надо знать длину комментария, которая указана в заверш. записи. Остается один выход. Сканировать файл сконца в поисках подписей заголовков и/или заверш. записи. НО! Нет никаких гарантий, что в комментарии или в сжатых данных не попадется подпись zip заголовка. Что и было проделано совершенно штатными средствами, правда, раром, - он умеет подставлять в качестве комментария другой файл, по идее текстовый, но я подсунул ему зип, в котором, естественно, попались эти самые 4 байтовые подписи заголовков. В результате получился файл, который не открывается WinZip-ом (v12.1) вообще, WinRar (v3.10) показывает список файлов, но ругается и не распаковывает, а 7z открывает но не архив, а тот самый файл, что был подсунут в качестве подписи. Так, как все-таки правильно парсить zip?! Андрей. PS: Пример см. во вложении. Делался так. 1. Вначале сделал 2 текстовых файла test.txt и comment.txt (в файлах по одному слову TEST и COMMENT соответственно). 2. WinRar-ом запаковал comment.txt в comment.zip 3. Запаковал test.txt в test.zip указав при запаковке взять комментарий из файла comment.zip PPS: Кстати дока по формату здесь: http://www.pkware.com/documents/casestudies/APPNOTE.TXT |
К сообщению приложены файлы:
Andrey Radchenko написано 29.07.2009 20:17 | |
Посмотрел исходники unzip на ftp://ftp.info-zip.org/pub/infozip/src/
Видно, что программеры наступили на теже грабли, и пришли к томуже выводу, что и я. Т. е. сканировать файл с конца в поисках подписи заверш. записи (ф-я find_ecrec в process.c). Такое решение, кстати, совершенно не решает указанную мною проблему с подписью в комментарии. Так что, вопрос не то, чтобы закрыт, просто, видимо, он вообще не имеет решения. Т.е. формат таки с изъяном. Хотя,... может есть идеи?
Добавление от 29.07.2009 20:44:
Это все мне нужно было для выколупывания текста из вордовского docx, который на самом деле zip с кучей xml в нутре.Стандартные библиотеки не юзаю, т.к. делаю не под винду и не под линух Вообще-то я уже сделал - тупо сканирую файл сначала, т.к. затык с длиной сжатых данных проявляется только если файл пишится в stdout (надеюсь), что в случае с docx, думаю, невозможно. Хотя стремление к совершенству не давало остановиться на достигнутом Кстати, прикол! Видимо микрософт показалось подозрительным, что файл в формате docx более чем в 5 раз меньше чем doc и щедро напихала в docx нулей (видимо, чтобы разница не так бросалась в глаза). Вообще такие поля разрешены и описаны в формате зипа, но они предназначены не для забивания нулями, а для хранения дополнительных атрибутов файлов, например NTFS. Кстати, из-за этих полей забитых нулями не работали скрипты распаковки зипов, которые удалось нарыть в инете, поэтому я и занялся написанием собственного парсера docx. |
Andrey Radchenko написано 30.07.2009 15:56 | |
цитата:Похоже, что так. По крайней мере, ни один из упоминаемых мною архиваторов не смог ни создать архив в поток ни прочитать его (сделанный в соответствии с форматом хекседиторе руками). Кроме рара, который, видимо, каталог вообще не читает, а бегает по заголовкам файлов с начала архива. Но тут он и попался, т.к. проигнорировал установленный 3 бит флагов (который означает, что CRC и длину файла нужно брать из каталога) и распаковал мне файл нулевой длины. |
цитата:
Konstantin Mironovich:
связаться с автором ?
Думаю, его уже достали этим вопросом разработчики архиваторов.
Спасибо всем. Тема закрыта.
Комментариев нет:
Отправить комментарий