// File: /workspace/github_cpp_makefile_star2_O1/jimmiebergmann[P]fbx-file/miniz.c
// Function: mz_zip_validate_file
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
{
    mz_zip_archive_file_stat file_stat;
    mz_zip_internal_state *pState;
    const mz_uint8 *pCentral_dir_header;
    mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
    mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
    mz_uint64 local_header_ofs = 0;
    mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
    mz_uint64 local_header_comp_size, local_header_uncomp_size;
    mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
    mz_bool has_data_descriptor;
    mz_uint32 local_header_bit_flags;

    mz_zip_array file_data_array;
    mz_zip_array_init(&file_data_array, 1);

    if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (file_index > pZip->m_total_files)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);

    if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
        return MZ_FALSE;

    /* A directory or zero length file */
    if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
        return MZ_TRUE;

    /* Encryption and patch files are not supported. */
    if (file_stat.m_is_encrypted)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

    /* This function only supports stored and deflate. */
    if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);

    if (!file_stat.m_is_supported)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);

    /* Read and parse the local directory entry. */
    local_header_ofs = file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
    local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
    local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
    local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
    local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
    has_data_descriptor = (local_header_bit_flags & 8) != 0;

    if (local_header_filename_len != strlen(file_stat.m_filename))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    if (local_header_filename_len)
    {
        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */
        if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
    {
        mz_uint32 extra_size_remaining = local_header_extra_len;
        const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        do
        {
            mz_uint32 field_id, field_data_size, field_total_size;

            if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            field_id = MZ_READ_LE16(pExtra_data);
            field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
            field_total_size = field_data_size + sizeof(mz_uint16) * 2;

            if (field_total_size > extra_size_remaining)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
            {
                const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);

                if (field_data_size < sizeof(mz_uint64) * 2)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
                    goto handle_failure;
                }

                local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
                local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64));

                found_zip64_ext_data_in_ldir = MZ_TRUE;
                break;
            }

            pExtra_data += field_total_size;
            extra_size_remaining -= field_total_size;
        } while (extra_size_remaining);
    }

    /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
    /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
    if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
    {
        mz_uint8 descriptor_buf[32];
        mz_bool has_id;
        const mz_uint8 *pSrc;
        mz_uint32 file_crc32;
        mz_uint64 comp_size = 0, uncomp_size = 0;

        mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s))
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
        pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf;

        file_crc32 = MZ_READ_LE32(pSrc);

        if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
        {
            comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
        }
        else
        {
            comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
        }

        if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }
    else
    {
        if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    mz_zip_array_clear(pZip, &file_data_array);

    if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
    {
        if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
            return MZ_FALSE;

        /* 1 more check to be sure, although the extract checks too. */
        if (uncomp_crc32 != file_stat.m_crc32)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            return MZ_FALSE;
        }
    }

    return MZ_TRUE;

handle_failure:
    mz_zip_array_clear(pZip, &file_data_array);
    return MZ_FALSE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x518, %rsp            # imm = 0x518
xorl %r13d, %r13d
movl %r13d, -0x60(%rbp)
movl %r13d, -0x48(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
movl $0x1, -0x68(%rbp)
testq %rdi, %rdi
je 0xa3d6
movq %rdi, %rbx
movq 0x68(%rdi), %r12
testq %r12, %r12
je 0xa3ca
cmpq $0x0, 0x28(%rbx)
je 0xa3ca
cmpq $0x0, 0x30(%rbx)
je 0xa3ca
cmpq $0x0, 0x48(%rbx)
je 0xa3ca
movl %esi, %r14d
movl 0x10(%rbx), %eax
cmpl %esi, %eax
jb 0xa3cf
movl %edx, %r15d
xorl %r13d, %r13d
cmpl %r14d, %eax
jbe 0xa3eb
movq 0x20(%r12), %rax
movl %r14d, %ecx
movl (%rax,%rcx,4), %edx
addq (%r12), %rdx
jmp 0xa3ed
testq %rbx, %rbx
je 0xa3d6
movl $0x18, 0x1c(%rbx)
movl %r13d, %eax
addq $0x518, %rsp            # imm = 0x518
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edx, %edx
leaq -0x538(%rbp), %rcx
leaq -0x60(%rbp), %r8
movq %rbx, %rdi
movl %r14d, %esi
callq 0xa87b
testl %eax, %eax
je 0xa3d6
cmpl $0x0, -0x4ec(%rbp)
jne 0xa84f
cmpq $0x0, -0x508(%rbp)
je 0xa84f
cmpl $0x0, -0x4e8(%rbp)
je 0xa434
movl $0x5, 0x1c(%rbx)
jmp 0xa3d6
movzwl -0x522(%rbp), %eax
testl $0xfff7, %eax           # imm = 0xFFF7
je 0xa44b
movl $0x4, 0x1c(%rbx)
jmp 0xa3d6
cmpl $0x0, -0x4e4(%rbp)
je 0xa50d
movq -0x4f8(%rbp), %rsi
movq 0x60(%rbx), %rdi
leaq -0xb0(%rbp), %rdx
movl $0x1e, %ecx
movq %rsi, -0x30(%rbp)
callq *0x48(%rbx)
cmpq $0x1e, %rax
jne 0xa519
cmpl $0x4034b50, -0xb0(%rbp) # imm = 0x4034B50
jne 0xa501
movzwl -0x96(%rbp), %eax
movq %rax, -0x38(%rbp)
movzwl -0x94(%rbp), %eax
movq %rax, -0x40(%rbp)
movl -0x9e(%rbp), %eax
movq %rax, -0x50(%rbp)
movl -0x9a(%rbp), %eax
movq %rax, -0x58(%rbp)
movl -0xa2(%rbp), %eax
movl %eax, -0x44(%rbp)
movzwl -0xaa(%rbp), %eax
movl %eax, -0x5c(%rbp)
leaq -0x4e0(%rbp), %rdi
callq 0x3110
movq -0x38(%rbp), %rsi
cmpq %rsi, %rax
jne 0xa501
movq -0x30(%rbp), %rax
leaq (%rax,%rsi), %rdx
addq $0x1e, %rdx
movq -0x40(%rbp), %rdi
leaq (%rdx,%rdi), %rcx
movq -0x510(%rbp), %rax
addq %rcx, %rax
cmpq (%rbx), %rax
jbe 0xa525
movl $0x9, 0x1c(%rbx)
jmp 0xa3d6
movl $0x6, 0x1c(%rbx)
jmp 0xa3d6
movl $0x14, 0x1c(%rbx)
jmp 0xa3d6
movq %rdi, %rax
movq %rdx, -0xb8(%rbp)
movq %rcx, -0xc0(%rbp)
cmpw %ax, %si
movl %eax, %ecx
cmoval %esi, %ecx
cmpq %rcx, -0x70(%rbp)
jae 0xa572
leaq -0x80(%rbp), %rsi
xorl %r13d, %r13d
movq %rbx, %rdi
movq %rcx, -0x88(%rbp)
movq -0x88(%rbp), %rdx
xorl %ecx, %ecx
callq 0xffe4
movq -0x88(%rbp), %rcx
testl %eax, %eax
je 0xa6b2
movq %rcx, -0x78(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0xa5c8
movq -0x30(%rbp), %rsi
addq $0x1e, %rsi
movq 0x60(%rbx), %rdi
movq -0x80(%rbp), %rdx
movq %rdx, -0x30(%rbp)
movq -0x38(%rbp), %r13
movq %r13, %rcx
callq *0x48(%rbx)
cmpq %r13, %rax
jne 0xa6a6
leaq -0x4e0(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x3270
testl %eax, %eax
je 0xa5c8
movl $0x1e, 0x1c(%rbx)
jmp 0xa85d
movl $0x0, -0x30(%rbp)
cmpl $0x0, -0x40(%rbp)
je 0xa6ee
cmpl $-0x1, -0x50(%rbp)
sete %al
cmpl $-0x1, -0x58(%rbp)
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0xa6ee
movq -0x80(%rbp), %rdx
movq 0x60(%rbx), %rdi
movq -0xb8(%rbp), %rsi
movq %rdx, -0x38(%rbp)
movq -0x40(%rbp), %r13
movq %r13, %rcx
callq *0x48(%rbx)
cmpq %r13, %rax
jne 0xa6be
movl $0x0, -0x30(%rbp)
cmpl $0x3, -0x40(%rbp)
jbe 0xa639
movq -0x38(%rbp), %rax
movzwl 0x2(%rax), %eax
leaq 0x4(%rax), %rdx
movq -0x40(%rbp), %rcx
subl %edx, %ecx
jae 0xa65a
movl $0x9, 0x1c(%rbx)
movl $0x1, %eax
xorl %ecx, %ecx
testl %eax, %eax
jne 0xa6d3
cmpl $0x0, -0x40(%rbp)
jne 0xa61f
jmp 0xa6da
movq -0x38(%rbp), %rsi
cmpw $0x1, (%rsi)
jne 0xa678
cmpw $0xf, %ax
ja 0xa684
movl $0x9, 0x1c(%rbx)
movl $0x2, %eax
jmp 0xa645
addq %rdx, -0x38(%rbp)
xorl %eax, %eax
movq %rcx, -0x40(%rbp)
jmp 0xa645
movq -0x38(%rbp), %rcx
movq 0x4(%rcx), %rax
movq %rax, -0x58(%rbp)
movq 0xc(%rcx), %rax
movq %rax, -0x50(%rbp)
movl $0x1, -0x30(%rbp)
movl $0x3, %eax
jmp 0xa645
movl $0x14, 0x1c(%rbx)
jmp 0xa85d
movl $0x10, 0x1c(%rbx)
jmp 0xa3d6
movl $0x14, 0x1c(%rbx)
movl $0x0, -0x30(%rbp)
movl $0x2, %ecx
jmp 0xa6da
cmpl $0x3, %eax
je 0xa6da
movl %eax, %ecx
cmpl $0x2, %ecx
je 0xa85d
xorl %r13d, %r13d
testl %ecx, %ecx
jne 0xa3d6
testb $0x8, -0x5c(%rbp)
sete %al
cmpq $0x0, -0x50(%rbp)
setne %cl
cmpl $0x0, -0x44(%rbp)
setne %dl
orb %cl, %dl
orb %al, %dl
je 0xa740
movl -0x44(%rbp), %eax
cmpl -0x518(%rbp), %eax
jne 0xa5bc
movq -0x50(%rbp), %rax
cmpq -0x510(%rbp), %rax
jne 0xa5bc
movq -0x58(%rbp), %rax
cmpq -0x508(%rbp), %rax
je 0xa7f0
jmp 0xa5bc
xorl %eax, %eax
movl 0x64(%r12), %ecx
orl -0x30(%rbp), %ecx
setne %al
movq 0x60(%rbx), %rdi
movq -0xc0(%rbp), %rsi
addq -0x510(%rbp), %rsi
leaq 0x10(,%rax,8), %r13
leaq -0xe0(%rbp), %rdx
movq %r13, %rcx
callq *0x48(%rbx)
movl $0x14, %esi
cmpq %r13, %rax
jne 0xa85a
movl -0xe0(%rbp), %esi
movl -0xdc(%rbp), %eax
xorl %edx, %edx
cmpl $0x8074b50, %esi        # imm = 0x8074B50
movl %esi, %ecx
cmovel %eax, %ecx
cmovel -0xd8(%rbp), %eax
sete %dl
movl -0xd8(%rbp,%rdx,4), %edx
movl -0x30(%rbp), %edi
orl 0x64(%r12), %edi
je 0xa7d1
xorl %edi, %edi
cmpl $0x8074b50, %esi        # imm = 0x8074B50
sete %dil
shlq $0x20, %rdx
orq %rdx, %rax
movq -0xd4(%rbp,%rdi,4), %rdx
movl $0x1e, %esi
cmpl -0x518(%rbp), %ecx
jne 0xa85a
cmpq -0x510(%rbp), %rax
jne 0xa85a
cmpq -0x508(%rbp), %rdx
jne 0xa85a
movq 0x40(%rbx), %rdi
movq -0x80(%rbp), %rsi
callq *0x30(%rbx)
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
btl $0xd, %r15d
jb 0xa84f
leaq 0x357(%rip), %rdx       # 0xab6b
leaq -0x48(%rbp), %rcx
xorl %r13d, %r13d
movq %rbx, %rdi
movl %r14d, %esi
xorl %r8d, %r8d
callq 0x9577
testl %eax, %eax
je 0xa3d6
movl -0x48(%rbp), %eax
movl $0x1, %r13d
cmpl -0x518(%rbp), %eax
je 0xa3d6
movl $0x1e, 0x1c(%rbx)
jmp 0xa873
movl $0x1, %r13d
jmp 0xa3d6
movl %esi, 0x1c(%rbx)
movq 0x40(%rbx), %rdi
movq -0x80(%rbp), %rsi
callq *0x30(%rbx)
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
xorl %r13d, %r13d
jmp 0xa3d6