nih-at/libzip

Regression failure to open empty, encrypted file

ralfjunker opened this issue · 0 comments

As of libzip v1.10.0, (1c55583), encrypted empty files of zero length no longer open. zip_fopen_index_encrypted() or zip_fopen_index() with default password set return a "Premature end of file" error.

The following code demonstrates the problem with these example ZIP archives:

void open_empty_encrypted_file(const char* fn) {
  char buf[256];
  int err, rc;
  zip_int64_t n;
  zip_t* zip;
  zip_file_t* zipFile;

  err = 0;
  zip = zip_open(fn, ZIP_RDONLY, &err);
  if (!zip) {
    printf("zip_open(\"%s\") = NULL - %s\n", fn);
  }

  n = zip_get_num_entries(zip, 0);
  printf("%Ld files in %s\n", n, fn);

  /* Open with correct password must succeed. */
  zipFile = zip_fopen_index_encrypted(zip, 0, 0, "1");
  if (!zipFile) {
    printf("zip_fopen_index_encrypted() = NULL - %s\n", zip_strerror(zip));
  }

  n = zip_fread(zipFile, buf, sizeof(buf));
  if (n < 0) {
    printf("zip_fread() = %Ld - %s\n", n, zip_strerror(zip));
  }

  zip_fclose(zipFile);

  /* Open with wrong password must fail. */
  zipFile = zip_fopen_index_encrypted(zip, 0, 0, "2");
  if (zipFile) {
    zip_fclose(zipFile);
    printf("zip_fopen_index() = NULL - %s\n", zip_strerror(zip));
  }

  zip_discard(zip);
}

This change seems to fix the problem:

--- a/lib/zip_source_zip_new.c
+++ b/lib/zip_source_zip_new.c
@@ -147,7 +147,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
     _zip_file_attributes_from_dirent(&attributes, de);
 
     have_comp_size = (st.valid & ZIP_STAT_COMP_SIZE) != 0;
-    if (compressed) {
+    if (compressed || encrypted) {
         if (have_comp_size && st.comp_size == 0) {
             src = zip_source_buffer_with_attributes_create(NULL, 0, 0, &attributes, error);
         }