Как узнать, заархивирован ли массив байтов

Как узнать, содержит ли массив байтов поток gzip? Мое приложение получает файлы из других приложений через http post с кодировкой Base64. В зависимости от реализации приложения, доставляющего файлы, массив байтов, выходящий из строки Base64, может быть заархивирован gzip. Как я могу распознать сжатые массивы? Я нашел какой-то метод, но я думаю, что он пойдет не так, если кто-то загрузит zip-файл или подготовлен "плохой" zip-файл

Это то, что я нашел и работает, но можно ли это как-то использовать?

C#

public static bool IsGZip(byte[] arr)
{
    return arr.Length >= 2 && arr[0] == 31 && arr[1] == 139;
}

ВБ.NET

Public Shared Function IsGZip(arr As Byte()) As Boolean
    Return arr.Length >= 2 AndAlso arr(0) = 31 AndAlso arr(1) = 139
End Function

Если IsGzip возвращает true, мое приложение распаковывает массив байтов.


person Kees de Wit    schedule 14.10.2013    source источник
comment
Это сомнительный подход: явное указание формата намного безопаснее - подумайте о редизайне. т.е. считается ли docx (или другой формат архивного файла документа) Zip или отдельным документом?   -  person Alexei Levenkov    schedule 14.10.2013
comment
Согласно RFC для Gzip, заголовок потока Gzip всегда будет начинаться с 0x1F8B, что и тестирует этот фрагмент кода. Это может дать ложное срабатывание, если я просто загружу случайный файл, который начинается с заголовка, но на самом деле не является содержимым Gzip. Вы также получите гораздо более положительный результат, если вы также проверите CRC потока. Единственный надежный способ узнать это — попробовать распаковать его.   -  person vcsjones    schedule 14.10.2013
comment
Приложения, которые доставляют файлы, являются внешними приложениями, которые через данные POST сообщают о том, что файлы заархивированы, но мы не можем полностью полагаться на тот факт, что они объявляют файл определенного типа. Мы должны выяснить для себя, чтобы обеспечить безопасность.   -  person Kees de Wit    schedule 14.10.2013
comment
@vcsjones: Что, если кто-то загрузит неправильный потоковый файл gzip? Под плохим я подразумеваю бесконечный файл, который превращает 10 байтов в 1PT или более.   -  person Kees de Wit    schedule 14.10.2013
comment
@KeesdeWit Вероятно, это DoS, вашему приложению не хватит памяти при попытке выделить этот массив байтов, но это, вероятно, произойдет до того, как вызов этой функции будет выполнен.   -  person vcsjones    schedule 14.10.2013
comment
@vcsjones: Как я могу предотвратить это?   -  person Kees de Wit    schedule 14.10.2013


Ответы (1)


Сделайте то, что вы делаете, убедитесь, что третий байт равен 8, а затем попробуйте его заархивировать. Этот последний шаг — единственный способ действительно узнать. Если gunzip не работает, используйте поток как есть.

person Mark Adler    schedule 14.10.2013