Exemplo n.º 1
0
static int file_archive_parse_file_init(file_archive_transfer_t *state,
                                        const char *file)
{
    state->backend = file_archive_get_default_file_backend();

    if (!state->backend)
        return -1;

    state->handle = file_archive_open(file);
    if (!state->handle)
        return -1;

    state->zip_size = file_archive_size(state->handle);
    if (state->zip_size < 22)
        return -1;

    state->data   = file_archive_data(state->handle);
    state->footer = state->data + state->zip_size - 22;

    for (;; state->footer--)
    {
        if (state->footer <= state->data + 22)
            return -1;
        if (read_le(state->footer, 4) == END_OF_CENTRAL_DIR_SIGNATURE)
        {
            unsigned comment_len = read_le(state->footer + 20, 2);
            if (state->footer + 22 + comment_len == state->data + state->zip_size)
                break;
        }
    }

    state->directory = state->data + read_le(state->footer + 16, 4);

    return 0;
}
Exemplo n.º 2
0
static int zip_parse_file_init(file_archive_transfer_t *state,
      const char *file)
{
   if (state->archive_size < 22)
      return -1;

   state->footer = state->data + state->archive_size - 22;

   for (;; state->footer--)
   {
      if (state->footer <= state->data + 22)
         return -1;
      if (read_le(state->footer, 4) == END_OF_CENTRAL_DIR_SIGNATURE)
      {
         unsigned comment_len = read_le(state->footer + 20, 2);
         if (state->footer + 22 + comment_len == state->data + state->archive_size)
            break;
      }
   }

   state->directory = state->data + read_le(state->footer + 16, 4);

   return 0;
}
Exemplo n.º 3
0
static int zip_parse_file_iterate_step_internal(
      file_archive_transfer_t *state, char *filename,
      const uint8_t **cdata,
      unsigned *cmode, uint32_t *size, uint32_t *csize,
      uint32_t *checksum, unsigned *payback)
{
   uint32_t offset;
   uint32_t namelength, extralength, commentlength,
            offsetNL, offsetEL;
   uint32_t signature = read_le(state->directory + 0, 4);

   if (signature != CENTRAL_FILE_HEADER_SIGNATURE)
      return 0;

   *cmode         = read_le(state->directory + 10, 2); /* compression mode, 0 = store, 8 = deflate */
   *checksum      = read_le(state->directory + 16, 4); /* CRC32 */
   *csize         = read_le(state->directory + 20, 4); /* compressed size */
   *size          = read_le(state->directory + 24, 4); /* uncompressed size */

   namelength     = read_le(state->directory + 28, 2); /* file name length */
   extralength    = read_le(state->directory + 30, 2); /* extra field length */
   commentlength  = read_le(state->directory + 32, 2); /* file comment length */

   if (namelength >= PATH_MAX_LENGTH)
      return -1;

   memcpy(filename, state->directory + 46, namelength); /* file name */

   offset         = read_le(state->directory + 42, 4); /* relative offset of local file header */
   offsetNL       = read_le(state->data + offset + 26, 2); /* file name length */
   offsetEL       = read_le(state->data + offset + 28, 2); /* extra field length */

   *cdata         = state->data + offset + 30 + offsetNL + offsetEL;

   *payback       = 46 + namelength + extralength + commentlength;

   return 1;
}
Exemplo n.º 4
0
static int file_archive_parse_file_iterate_step_internal(
    file_archive_transfer_t *state, char *filename,
    const uint8_t **cdata,
    unsigned *cmode, uint32_t *size, uint32_t *csize,
    uint32_t *checksum, unsigned *payback)
{
    uint32_t offset;
    uint32_t namelength, extralength, commentlength,
             offsetNL, offsetEL;
    uint32_t signature = read_le(state->directory + 0, 4);

    if (signature != CENTRAL_FILE_HEADER_SIGNATURE)
        return 0;

    *cmode         = read_le(state->directory + 10, 2);
    *checksum      = read_le(state->directory + 16, 4);
    *csize         = read_le(state->directory + 20, 4);
    *size          = read_le(state->directory + 24, 4);

    namelength     = read_le(state->directory + 28, 2);
    extralength    = read_le(state->directory + 30, 2);
    commentlength  = read_le(state->directory + 32, 2);

    if (namelength >= PATH_MAX_LENGTH)
        return -1;

    memcpy(filename, state->directory + 46, namelength);

    offset         = read_le(state->directory + 42, 4);
    offsetNL       = read_le(state->data + offset + 26, 2);
    offsetEL       = read_le(state->data + offset + 28, 2);

    *cdata         = state->data + offset + 30 + offsetNL + offsetEL;

    *payback       = 46 + namelength + extralength + commentlength;

    return 1;
}
Exemplo n.º 5
0
bool zlib_parse_file(const char *file, zlib_file_cb file_cb, void *userdata)
{
   const uint8_t *footer = NULL;
   const uint8_t *directory = NULL;

   bool ret = true;
   const uint8_t *data = NULL;

   const struct zlib_file_backend *backend = zlib_get_default_file_backend();
   if (!backend)
      return NULL;

   ssize_t zip_size = 0;
   void *handle = backend->open(file);
   if (!handle)
      GOTO_END_ERROR();

   zip_size = backend->size(handle);
   if (zip_size < 22)
      GOTO_END_ERROR();

   data = backend->data(handle);

   footer = data + zip_size - 22;
   for (;; footer--)
   {
      if (footer <= data + 22)
         GOTO_END_ERROR();
      if (read_le(footer, 4) == 0x06054b50)
      {
         unsigned comment_len = read_le(footer + 20, 2);
         if (footer + 22 + comment_len == data + zip_size)
            break;
      }
   }

   directory = data + read_le(footer + 16, 4);

   for (;;)
   {
      uint32_t signature = read_le(directory + 0, 4);
      if (signature != 0x02014b50)
         break;

      unsigned cmode = read_le(directory + 10, 2);
      uint32_t crc32 = read_le(directory + 16, 4);
      uint32_t csize = read_le(directory + 20, 4);
      uint32_t size  = read_le(directory + 24, 4);

      unsigned namelength    = read_le(directory + 28, 2);
      unsigned extralength   = read_le(directory + 30, 2);
      unsigned commentlength = read_le(directory + 32, 2);

      char filename[PATH_MAX] = {0};
      if (namelength >= PATH_MAX)
         GOTO_END_ERROR();

      memcpy(filename, directory + 46, namelength);

      uint32_t offset   = read_le(directory + 42, 4);
      unsigned offsetNL = read_le(data + offset + 26, 2);
      unsigned offsetEL = read_le(data + offset + 28, 2);

      const uint8_t *cdata = data + offset + 30 + offsetNL + offsetEL;

      //RARCH_LOG("OFFSET: %u, CSIZE: %u, SIZE: %u.\n", offset + 30 + offsetNL + offsetEL, csize, size);

      if (!file_cb(filename, cdata, cmode, csize, size, crc32, userdata))
         break;

      directory += 46 + namelength + extralength + commentlength;
   }

end:
   if (handle)
      backend->free(handle);
   return ret;
}