// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/modules/zip.c
// Function: ef_infozipmac
static void ef_infozipmac(deark *c, lctx *d, struct extra_item_info_struct *eii)
{
	i64 pos = eii->dpos;
	i64 dpos;
	i64 ulen;
	i64 cmpr_attr_size;
	UI flags;
	int cmpr_meth;
	const struct cmpr_meth_info *cmi = NULL;
	struct de_fourcc filetype;
	struct de_fourcc creator;
	de_ucstring *flags_str = NULL;
	dbuf *attr_data = NULL;
	int ret;
	i64 create_time_raw;
	i64 create_time_offset;
	i64 mod_time_raw;
	i64 mod_time_offset;
	i64 backup_time_raw;
	i64 backup_time_offset;
	struct de_timestamp tmp_timestamp;
	int charset;
	u32 crc_reported = 0;
	UI dcflags = 0;
	struct de_stringreaderdata *srd;

	if(eii->dlen<14) goto done;

	ulen = de_getu32le_p(&pos);
	de_dbg(c, "uncmpr. finder attr. size: %d", (int)ulen);

	flags = (UI)de_getu16le_p(&pos);
	flags_str = ucstring_create(c);
	if(flags&0x0001) ucstring_append_flags_item(flags_str, "data_fork");
	if(flags&0x0002) ucstring_append_flags_item(flags_str, "0x0002"); // something about the filename
	ucstring_append_flags_item(flags_str,
		(flags&0x0004)?"uncmpressed_attribute_data":"compressed_attribute_data");
	if(flags&0x0008) ucstring_append_flags_item(flags_str, "64-bit_times");
	if(flags&0x0010) ucstring_append_flags_item(flags_str, "no_timezone_offsets");
	de_dbg(c, "flags: 0x%04x (%s)", flags, ucstring_getpsz(flags_str));

	dbuf_read_fourcc(c->infile, pos, &filetype, 4, 0x0);
	de_dbg(c, "filetype: '%s'", filetype.id_dbgstr);
	pos += 4;
	dbuf_read_fourcc(c->infile, pos, &creator, 4, 0x0);
	de_dbg(c, "creator: '%s'", creator.id_dbgstr);
	pos += 4;

	if(eii->is_central) goto done;

	if(flags&0x0004) { // Uncompressed attribute data
		cmpr_meth = 0;
	}
	else {
		dcflags |= 0x1; // CRC is known
		cmpr_meth = (int)de_getu16le_p(&pos);
		cmi = get_cmpr_meth_info(cmpr_meth);
		de_dbg(c, "finder attr. cmpr. method: %d (%s)", cmpr_meth, (cmi ? cmi->name : "?"));

		crc_reported = (u32)de_getu32le_p(&pos);
		de_dbg(c, "finder attr. data crc (reported): 0x%08x", (UI)crc_reported);
	}

	// The rest of the data is Finder attribute data
	cmpr_attr_size = eii->dpos+eii->dlen - pos;
	de_dbg(c, "cmpr. finder attr. size: %d", (int)cmpr_attr_size);
	if(ulen<1 || ulen>1000000) goto done;

	// Type 6 (implode) compression won't work here, because it needs
	// additional parameters seemingly not provided by the Finder attr data.
	if(cmpr_meth==6 || !is_compression_method_supported(d, cmi)) {
		de_warn(c, "Finder attribute data: Unsupported compression method: %d (%s)",
			cmpr_meth, (cmi ? cmi->name : "?"));
		goto done;
	}

	// Decompress and decode the Finder attribute data
	attr_data = dbuf_create_membuf(c, ulen, 0x1);
	ret = do_decompress_attrib_data(c, d, pos, cmpr_attr_size,
		attr_data, ulen, crc_reported, cmpr_meth, cmi, dcflags, "finder attr. data");
	if(!ret) {
		de_warn(c, "Failed to decompress finder attribute data");
		goto done;
	}

	dpos = 0;
	dpos += 2; // Finder flags
	dpos += 4; // Icon location
	dpos += 2; // Folder
	dpos += 16; // FXInfo
	dpos += 1; // file version number
	dpos += 1; // dir access rights

	if(flags&0x0008) goto done; // We don't support 64-bit times
	if(flags&0x0010) goto done; // We want timezone offsets
	if(attr_data->len - dpos < 6*4) goto done;

	create_time_raw = dbuf_getu32le_p(attr_data, &dpos);
	mod_time_raw    = dbuf_getu32le_p(attr_data, &dpos);
	backup_time_raw = dbuf_getu32le_p(attr_data, &dpos);
	create_time_offset = dbuf_geti32le(attr_data, dpos); dpos += 4;
	mod_time_offset    = dbuf_geti32le(attr_data, dpos); dpos += 4;
	backup_time_offset = dbuf_geti32le(attr_data, dpos); dpos += 4;

	handle_mac_time(c, d, create_time_raw, create_time_offset, &tmp_timestamp, "create time");
	if(create_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_CREATE, &tmp_timestamp, 40);
	}
	handle_mac_time(c, d, mod_time_raw,    mod_time_offset,    &tmp_timestamp, "mod time   ");
	if(mod_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_MODIFY, &tmp_timestamp, 40);
	}
	handle_mac_time(c, d, backup_time_raw, backup_time_offset, &tmp_timestamp, "backup time");
	if(backup_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_BACKUP, &tmp_timestamp, 40);
	}

	// Expecting 2 bytes for charset, and at least 2 more for the 2 NUL-terminated
	// strings that follow.
	if(attr_data->len - dpos < 4) goto done;

	charset = (int)dbuf_getu16le_p(attr_data, &dpos);
	de_dbg(c, "charset for fullpath/comment: %d", charset);

	// TODO: Can we use the correct encoding?
	srd = dbuf_read_string(attr_data, dpos, attr_data->len-dpos, DE_DBG_MAX_STRLEN,
		DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
	de_dbg(c, "fullpath: \"%s\"", ucstring_getpsz(srd->str));
	dpos += srd->bytes_consumed;
	de_destroy_stringreaderdata(c, srd);

	srd = dbuf_read_string(attr_data, dpos, attr_data->len-dpos, DE_DBG_MAX_STRLEN,
		DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
	de_dbg(c, "comment: \"%s\"", ucstring_getpsz(srd->str));
	dpos += srd->bytes_consumed;
	de_destroy_stringreaderdata(c, srd);

done:
	ucstring_destroy(flags_str);
	dbuf_close(attr_data);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq 0x8(%rdx), %rax
movq %rax, 0x8(%rsp)
cmpq $0xe, 0x10(%rdx)
jge 0xdef98
xorl %r12d, %r12d
xorl %ebx, %ebx
jmp 0xdf1fa
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
movq 0x18(%rdi), %rdi
leaq 0x8(%rsp), %rbx
movq %rbx, %rsi
callq 0xeed83
movq %rax, %r13
leaq 0x651ef(%rip), %rsi     # 0x1441ab
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe8617
movq 0x18(%r14), %rdi
movq %rbx, %rsi
callq 0xeebeb
movq %rax, %rbp
movq %r14, %rdi
callq 0xf6410
movq %rax, %rbx
testb $0x1, %bpl
je 0xdeff8
leaq 0x651d9(%rip), %rsi     # 0x1441c9
movq %rbx, %rdi
callq 0xf7105
testb $0x2, %bpl
je 0xdf00d
leaq 0x651ce(%rip), %rsi     # 0x1441d3
movq %rbx, %rdi
callq 0xf7105
testb $0x4, %bpl
leaq 0x651dd(%rip), %rax     # 0x1441f5
leaq 0x651bb(%rip), %rsi     # 0x1441da
cmoveq %rax, %rsi
movq %rbx, %rdi
callq 0xf7105
testb $0x8, %bpl
je 0xdf040
leaq 0x651d7(%rip), %rsi     # 0x14420f
movq %rbx, %rdi
callq 0xf7105
testb $0x10, %bpl
je 0xdf055
leaq 0x651cf(%rip), %rsi     # 0x14421c
movq %rbx, %rdi
callq 0xf7105
movq %rbx, %rdi
callq 0xf705c
leaq 0x662fa(%rip), %rsi     # 0x14535e
movq %r14, %rdi
movl %ebp, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0xe8617
movq 0x18(%r14), %rdi
movq 0x8(%rsp), %rsi
leaq 0x88(%rsp), %rdx
movl $0x4, %ecx
xorl %r8d, %r8d
callq 0xf1762
leaq 0x98(%rsp), %rdx
leaq 0x3589b(%rip), %rsi     # 0x11493b
movq %r14, %rdi
xorl %eax, %eax
callq 0xe8617
movq 0x8(%rsp), %rsi
addq $0x4, %rsi
movq %rsi, 0x8(%rsp)
movq 0x18(%r14), %rdi
leaq 0x58(%rsp), %rdx
movl $0x4, %ecx
xorl %r8d, %r8d
callq 0xf1762
leaq 0x68(%rsp), %rdx
leaq 0x55211(%rip), %rsi     # 0x1342eb
movq %r14, %rdi
xorl %eax, %eax
callq 0xe8617
movq 0x8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x8(%rsp)
cmpl $0x0, 0x30(%r15)
jne 0xdf1f7
movq $0x0, 0x28(%rsp)
movq %r13, 0x18(%rsp)
testb $0x4, %bpl
movq %r12, 0x40(%rsp)
jne 0xdf155
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %rsi
callq 0xeebeb
movq %rax, %r13
leaq 0xaee62(%rip), %rax     # 0x18df90
leaq 0x4d01c(%rip), %rcx     # 0x12c151
xorl %edx, %edx
cmpl %r13d, (%rdx,%rax)
je 0xdf16c
addq $0x18, %rdx
cmpq $0x210, %rdx            # imm = 0x210
jne 0xdf137
movq $0x0, 0x10(%rsp)
jmp 0xdf17a
movq $0x0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
xorl %r13d, %r13d
jmp 0xdf1c5
leaq (%rax,%rdx), %rcx
movq %rcx, 0x10(%rsp)
movq 0x8(%rdx,%rax), %rcx
leaq 0x650af(%rip), %rsi     # 0x144230
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe8617
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %r12
movq %r12, %rsi
callq 0xeed83
leaq 0x650ad(%rip), %rsi     # 0x144253
movq %r14, %rdi
movq %rax, 0x28(%rsp)
movl %eax, %edx
xorl %eax, %eax
callq 0xe8617
movl $0x1, %eax
movq %rax, 0x20(%rsp)
movq (%r12), %rax
movq 0x10(%r15), %r12
addq 0x8(%r15), %r12
subq %rax, %r12
leaq 0x64fd6(%rip), %rsi     # 0x1441ad
movq %r14, %rdi
movl %r12d, %edx
xorl %eax, %eax
callq 0xe8617
movq 0x18(%rsp), %rax
addq $-0xf4241, %rax         # imm = 0xFFF0BDBF
cmpq $-0xf4240, %rax         # imm = 0xFFF0BDC0
jae 0xdf21c
xorl %r12d, %r12d
movq %rbx, %rdi
callq 0xf6753
movq %r12, %rdi
callq 0xf052b
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x6, %r13d
jne 0xdf235
movq 0x10(%rsp), %rax
testq %rax, %rax
jne 0xdf51c
jmp 0xdf522
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0xdf522
cmpq $0x0, 0x10(%rax)
je 0xdf51c
movq %r14, %rdi
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rsi
movl $0x1, %edx
callq 0xf09c5
movq 0x8(%rsp), %rdx
subq $0x8, %rsp
leaq 0x65046(%rip), %r10     # 0x1442bb
movq %r14, %rdi
movq 0x48(%rsp), %rsi
movq %r12, %rcx
movq %rax, %r12
movq %rax, %r8
movq 0x20(%rsp), %r9
pushq %r10
pushq 0x30(%rsp)
pushq 0x28(%rsp)
pushq %r13
pushq 0x50(%rsp)
callq 0xdfbd8
addq $0x30, %rsp
testl %eax, %eax
je 0xdf545
movq $0x1a, 0x48(%rsp)
testb $0x18, %bpl
jne 0xdf1fa
cmpq $0x32, 0x18(%r12)
jl 0xdf1fa
leaq 0x48(%rsp), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0xeed83
movq %rax, %r13
movq %r12, %rdi
movq %rbp, %rsi
callq 0xeed83
movq %rax, 0x28(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0xeed83
movq %rax, 0x10(%rsp)
movq (%rbp), %rsi
movq %r12, %rdi
callq 0xeedfa
movq %rax, 0x50(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, %rdi
callq 0xeedfa
movq %rax, 0x20(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, 0x18(%rsp)
movq %r12, %rdi
callq 0xeedfa
movq %rax, 0x40(%rsp)
addq $0x4, (%rbp)
leaq 0x500ce(%rip), %r8      # 0x12f420
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq %r13, %rsi
movq 0x50(%rsp), %rdx
callq 0xdfde0
testq %r13, %r13
jle 0xdf38d
cmpb $0x0, 0x30(%rsp)
je 0xdf38d
movq 0x20(%r15), %rax
cmpl $0x28, 0x70(%rax)
jg 0xdf38d
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x60(%rax)
movl $0x28, 0x70(%rax)
leaq 0x4cff8(%rip), %r8      # 0x12c38c
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x28(%rsp), %r12
movq %r12, %rsi
movq 0x20(%rsp), %rdx
callq 0xdfde0
testq %r12, %r12
jle 0xdf3d4
cmpb $0x0, 0x30(%rsp)
je 0xdf3d4
movq 0x20(%r15), %rax
cmpl $0x28, 0x58(%rax)
jg 0xdf3d4
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x48(%rax)
movl $0x28, 0x58(%rax)
leaq 0x64f1d(%rip), %r8      # 0x1442f8
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x10(%rsp), %r12
movq %r12, %rsi
movq 0x40(%rsp), %rdx
callq 0xdfde0
testq %r12, %r12
movq 0x18(%rsp), %r12
jle 0xdf429
cmpb $0x0, 0x30(%rsp)
je 0xdf429
movq 0x20(%r15), %rax
cmpl $0x28, 0xb8(%rax)
jg 0xdf429
movups 0x30(%rsp), %xmm0
movups %xmm0, 0xa8(%rax)
movl $0x28, 0xb8(%rax)
movq 0x18(%r12), %rax
subq 0x48(%rsp), %rax
cmpq $0x4, %rax
jl 0xdf1fa
leaq 0x48(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0xeebeb
leaq 0x64eb0(%rip), %rsi     # 0x144304
movq %r14, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0xe8617
movq (%r15), %rsi
movq 0x18(%r12), %rdx
subq %rsi, %rdx
movl $0x1f4, %ecx            # imm = 0x1F4
movq %r12, %rdi
movl $0x1, %r8d
movl $0x1, %r9d
callq 0xef87c
movq %rax, %r12
movq 0x18(%rax), %rdi
callq 0xf705c
leaq 0x64e8e(%rip), %rsi     # 0x144325
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xe8617
movq (%r12), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r12, %rsi
callq 0xefaca
movq (%r15), %rsi
movq 0x18(%rsp), %rax
movq 0x18(%rax), %rdx
subq %rsi, %rdx
movl $0x1f4, %ecx            # imm = 0x1F4
movq 0x18(%rsp), %rdi
movl $0x1, %r8d
movl $0x1, %r9d
callq 0xef87c
movq %rax, %r12
movq 0x18(%rax), %rdi
callq 0xf705c
leaq 0x3538d(%rip), %rsi     # 0x114880
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xe8617
movq (%r12), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r12, %rsi
movq 0x18(%rsp), %r12
callq 0xefaca
jmp 0xdf1fa
movq 0x8(%rax), %rcx
jmp 0xdf529
leaq 0x4cc28(%rip), %rcx     # 0x12c151
leaq 0x64d4c(%rip), %rsi     # 0x14427c
xorl %r12d, %r12d
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe8faa
jmp 0xdf1fa
leaq 0x64d81(%rip), %rsi     # 0x1442cd
movq %r14, %rdi
xorl %eax, %eax
callq 0xe8faa
jmp 0xdf1fa