// File: /workspace/github_c_makefile_star2_O1/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 0xdf9a0
xorl %r12d, %r12d
xorl %ebx, %ebx
jmp 0xdfbf6
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
movq 0x18(%rdi), %rdi
leaq 0x8(%rsp), %rbx
movq %rbx, %rsi
callq 0xef3a0
movq %rax, %r13
leaq 0x64307(%rip), %rsi     # 0x143ccb
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe9226
movq 0x18(%r14), %rdi
movq %rbx, %rsi
callq 0xef1ed
movq %rax, %rbp
movq %r14, %rdi
callq 0xf6870
movq %rax, %rbx
testb $0x1, %bpl
je 0xdfa00
leaq 0x642f1(%rip), %rsi     # 0x143ce9
movq %rbx, %rdi
callq 0xf7566
testb $0x2, %bpl
je 0xdfa15
leaq 0x642e6(%rip), %rsi     # 0x143cf3
movq %rbx, %rdi
callq 0xf7566
testb $0x4, %bpl
leaq 0x642f5(%rip), %rax     # 0x143d15
leaq 0x642d3(%rip), %rsi     # 0x143cfa
cmoveq %rax, %rsi
movq %rbx, %rdi
callq 0xf7566
testb $0x8, %bpl
je 0xdfa48
leaq 0x642ef(%rip), %rsi     # 0x143d2f
movq %rbx, %rdi
callq 0xf7566
testb $0x10, %bpl
je 0xdfa5d
leaq 0x642e7(%rip), %rsi     # 0x143d3c
movq %rbx, %rdi
callq 0xf7566
movq %rbx, %rdi
callq 0xf74bd
leaq 0x65412(%rip), %rsi     # 0x144e7e
movq %r14, %rdi
movl %ebp, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0xe9226
movq 0x18(%r14), %rdi
movq 0x8(%rsp), %rsi
leaq 0x88(%rsp), %rdx
movl $0x4, %ecx
xorl %r8d, %r8d
callq 0xf1d74
leaq 0x98(%rsp), %rdx
leaq 0x34db8(%rip), %rsi     # 0x114860
movq %r14, %rdi
xorl %eax, %eax
callq 0xe9226
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 0xf1d74
leaq 0x68(%rsp), %rdx
leaq 0x54411(%rip), %rsi     # 0x133ef3
movq %r14, %rdi
xorl %eax, %eax
callq 0xe9226
addq $0x4, 0x8(%rsp)
cmpl $0x0, 0x30(%r15)
jne 0xdfbf3
movq $0x0, 0x28(%rsp)
movq %r13, 0x10(%rsp)
testb $0x4, %bpl
movq %r12, 0x40(%rsp)
jne 0xdfb47
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %rsi
callq 0xef1ed
movq %rax, %r13
xorl %edx, %edx
leaq 0xae460(%rip), %rax     # 0x18df90
xorl %ecx, %ecx
cmpl %r13d, (%rcx,%rax)
je 0xdfb5e
addq $0x18, %rcx
cmpq $0x210, %rcx            # imm = 0x210
jne 0xdfb32
jmp 0xdfb64
movq $0x0, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
xorl %r13d, %r13d
jmp 0xdfbbf
addq %rcx, %rax
movq %rax, %rdx
testq %rdx, %rdx
movq %rdx, 0x18(%rsp)
je 0xdfb74
movq 0x8(%rdx), %rcx
jmp 0xdfb7b
leaq 0x4c2ee(%rip), %rcx     # 0x12be69
leaq 0x641ce(%rip), %rsi     # 0x143d50
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe9226
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %rsi
callq 0xef3a0
leaq 0x641cf(%rip), %rsi     # 0x143d73
movq %r14, %rdi
movq %rax, 0x28(%rsp)
movl %eax, %edx
xorl %eax, %eax
callq 0xe9226
movl $0x1, %eax
movq %rax, 0x20(%rsp)
movq 0x10(%r15), %r12
addq 0x8(%r15), %r12
subq 0x8(%rsp), %r12
leaq 0x640fa(%rip), %rsi     # 0x143ccd
movq %r14, %rdi
movl %r12d, %edx
xorl %eax, %eax
callq 0xe9226
movq 0x10(%rsp), %rax
addq $-0xf4241, %rax         # imm = 0xFFF0BDBF
cmpq $-0xf4240, %rax         # imm = 0xFFF0BDC0
jae 0xdfc18
xorl %r12d, %r12d
movq %rbx, %rdi
callq 0xf6bb0
movq %r12, %rdi
callq 0xf0b13
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x6, %r13d
movq 0x18(%rsp), %rax
jne 0xdfc35
testq %rax, %rax
je 0xdff13
movq 0x8(%rax), %rcx
jmp 0xdff1a
testq %rax, %rax
je 0xdff13
cmpq $0x0, 0x10(%rax)
je 0xdfc23
movq %r14, %rdi
movq 0x10(%rsp), %rsi
movq %rax, 0x18(%rsp)
movl $0x1, %edx
callq 0xf0faf
movq 0x8(%rsp), %rdx
subq $0x8, %rsp
leaq 0x6416f(%rip), %r10     # 0x143ddb
movq %r14, %rdi
movq 0x48(%rsp), %rsi
movq %r12, %rcx
movq %rax, %r12
movq %rax, %r8
movq 0x18(%rsp), %r9
pushq %r10
pushq 0x30(%rsp)
pushq 0x30(%rsp)
pushq %r13
pushq 0x50(%rsp)
callq 0xe05ce
addq $0x30, %rsp
testl %eax, %eax
je 0xdff36
movq $0x1a, 0x48(%rsp)
testb $0x18, %bpl
jne 0xdfbf6
cmpq $0x32, 0x18(%r12)
jl 0xdfbf6
leaq 0x48(%rsp), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0xef3a0
movq %rax, %r13
movq %r12, %rdi
movq %rbp, %rsi
callq 0xef3a0
movq %rax, 0x28(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0xef3a0
movq %rax, 0x18(%rsp)
movq (%rbp), %rsi
movq %r12, %rdi
callq 0xef417
movq %rax, 0x50(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, %rdi
callq 0xef417
movq %rax, 0x20(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, 0x10(%rsp)
movq %r12, %rdi
callq 0xef417
movq %rax, 0x40(%rsp)
addq $0x4, (%rbp)
leaq 0x4f3f4(%rip), %r8      # 0x12f13d
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq %r13, %rsi
movq 0x50(%rsp), %rdx
callq 0xe07df
testq %r13, %r13
jle 0xdfd84
cmpb $0x0, 0x30(%rsp)
je 0xdfd84
movq 0x20(%r15), %rax
cmpl $0x28, 0x70(%rax)
jg 0xdfd84
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x60(%rax)
movl $0x28, 0x70(%rax)
leaq 0x4c319(%rip), %r8      # 0x12c0a4
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x28(%rsp), %r12
movq %r12, %rsi
movq 0x20(%rsp), %rdx
callq 0xe07df
testq %r12, %r12
jle 0xdfdcb
cmpb $0x0, 0x30(%rsp)
je 0xdfdcb
movq 0x20(%r15), %rax
cmpl $0x28, 0x58(%rax)
jg 0xdfdcb
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x48(%rax)
movl $0x28, 0x58(%rax)
leaq 0x64046(%rip), %r8      # 0x143e18
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x18(%rsp), %r12
movq %r12, %rsi
movq 0x40(%rsp), %rdx
callq 0xe07df
testq %r12, %r12
movq 0x10(%rsp), %r12
jle 0xdfe20
cmpb $0x0, 0x30(%rsp)
je 0xdfe20
movq 0x20(%r15), %rax
cmpl $0x28, 0xb8(%rax)
jg 0xdfe20
movups 0x30(%rsp), %xmm0
movups %xmm0, 0xa8(%rax)
movl $0x28, 0xb8(%rax)
movq 0x18(%r12), %rax
subq 0x48(%rsp), %rax
cmpq $0x4, %rax
jl 0xdfbf6
leaq 0x48(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0xef1ed
leaq 0x63fd9(%rip), %rsi     # 0x143e24
movq %r14, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0xe9226
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 0xefe67
movq %rax, %r12
movq 0x18(%rax), %rdi
callq 0xf74bd
leaq 0x63fb7(%rip), %rsi     # 0x143e45
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xe9226
movq (%r12), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r12, %rsi
callq 0xf00aa
movq (%r15), %rsi
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rdx
subq %rsi, %rdx
movl $0x1f4, %ecx            # imm = 0x1F4
movq 0x10(%rsp), %rdi
movl $0x1, %r8d
movl $0x1, %r9d
callq 0xefe67
movq %rax, %r12
movq 0x18(%rax), %rdi
callq 0xf74bd
leaq 0x348bb(%rip), %rsi     # 0x1147a5
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xe9226
movq (%r12), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r12, %rsi
movq 0x10(%rsp), %r12
callq 0xf00aa
jmp 0xdfbf6
leaq 0x4bf4f(%rip), %rcx     # 0x12be69
leaq 0x63e7b(%rip), %rsi     # 0x143d9c
xorl %r12d, %r12d
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xe9b27
jmp 0xdfbf6
leaq 0x63eb0(%rip), %rsi     # 0x143ded
movq %r14, %rdi
xorl %eax, %eax
callq 0xe9b27
jmp 0xdfbf6