static const ut8 *r_bin_dwarf_parse_attr_value(const ut8 *obuf, int obuf_len,
		RBinDwarfAttrSpec *spec, RBinDwarfAttrValue *value,
		const RBinDwarfCompUnitHdr *hdr,
		const ut8 *debug_str, size_t debug_str_len) {
	const ut8 *buf = obuf;
	const ut8 *buf_end = obuf + obuf_len;
	size_t j;

	if (!spec || !value || !hdr || !obuf || obuf_len < 1) {
		return NULL;
	}

	value->form = spec->attr_form;
	value->name = spec->attr_name;
	value->encoding.block.data = NULL;
	value->encoding.str_struct.string = NULL;
	value->encoding.str_struct.offset = 0;

	switch (spec->attr_form) {
	case DW_FORM_addr:
		switch (hdr->pointer_size) {
		case 1:
			value->encoding.address = READ (buf, ut8);
			break;
		case 2:
			value->encoding.address = READ (buf, ut16);
			break;
		case 4:
			value->encoding.address = READ (buf, ut32);
			break;
		case 8:
			value->encoding.address = READ (buf, ut64);
			break;
		default:
			eprintf ("DWARF: Unexpected pointer size: %u\n", (unsigned)hdr->pointer_size);
			return NULL;
		}
		break;
	case DW_FORM_block2:
		value->encoding.block.length = READ (buf, ut16);
		if (value->encoding.block.length > 0) {
			value->encoding.block.data = calloc (sizeof(ut8), value->encoding.block.length);
			for (j = 0; j < value->encoding.block.length; j++) {
				value->encoding.block.data[j] = READ (buf, ut8);
			}
		}
		break;
	case DW_FORM_block4:
		value->encoding.block.length = READ (buf, ut32);
		if (value->encoding.block.length > 0) {
			ut8 *data = calloc (sizeof (ut8), value->encoding.block.length);
			if (data) {
				for (j = 0; j < value->encoding.block.length; j++) {
					data[j] = READ (buf, ut8);
				}
			}
			value->encoding.block.data = data;
		}
		break;
#if 0
	case DW_FORM_data2:
		value->encoding.data = READ (buf, ut16);
		break;
	case DW_FORM_data4:
		value->encoding.data = READ (buf, ut32);
		break;
	case DW_FORM_data8:
		value->encoding.data = READ (buf, ut64);
		break;
#endif
	case DW_FORM_string:
		value->encoding.str_struct.string = *buf? strdup ((const char*)buf) : NULL;
		buf += (strlen ((const char*)buf) + 1);
		break;
	case DW_FORM_block:
		buf = r_uleb128 (buf, buf_end - buf, &value->encoding.block.length);
		if (!buf) {
			return NULL;
		}
		value->encoding.block.data = calloc (sizeof (ut8), value->encoding.block.length);
		if (value->encoding.block.data) {
			for (j = 0; j < value->encoding.block.length; j++) {
				value->encoding.block.data[j] = READ (buf, ut8);
			}
		}
		break;
	case DW_FORM_block1:
		value->encoding.block.length = READ (buf, ut8);
		value->encoding.block.data = calloc (sizeof (ut8), value->encoding.block.length + 1);
		if (value->encoding.block.data) {
			for (j = 0; j < value->encoding.block.length; j++) {
				value->encoding.block.data[j] = READ (buf, ut8);
			}
		}
		break;
	case DW_FORM_flag:
		value->encoding.flag = READ (buf, ut8);
		break;
	case DW_FORM_sdata:
		buf = r_leb128 (buf, &value->encoding.sdata);
		break;
	case DW_FORM_strp:
		value->encoding.str_struct.offset = READ (buf, ut32);
		if (debug_str && value->encoding.str_struct.offset < debug_str_len) {
			value->encoding.str_struct.string = strdup (
				(const char *)(debug_str +
					value->encoding.str_struct.offset));
		} else {
			value->encoding.str_struct.string = NULL;
		}
		break;
	case DW_FORM_udata:
		{
			ut64 ndata = 0;
			const ut8 *data = (const ut8*)&ndata;
			buf = r_uleb128 (buf, R_MIN (sizeof (data), (size_t)(buf_end - buf)), &ndata);
			memcpy (&value->encoding.data, data, sizeof (value->encoding.data));
			value->encoding.str_struct.string = NULL;
		}
		break;
	case DW_FORM_ref_addr:
		value->encoding.reference = READ (buf, ut64); // addr size of machine
		break;
	case DW_FORM_ref1:
		value->encoding.reference = READ (buf, ut8);
		break;
	case DW_FORM_ref2:
		value->encoding.reference = READ (buf, ut16);
		break;
	case DW_FORM_ref4:
		value->encoding.reference = READ (buf, ut32);
		break;
	case DW_FORM_ref8:
		value->encoding.reference = READ (buf, ut64);
		break;
	case DW_FORM_data1:
		value->encoding.data = READ (buf, ut8);
		break;
	default:
		eprintf ("Unknown DW_FORM 0x%02"PFMT64x"\n", spec->attr_form);
		value->encoding.data = 0;
		return NULL;
	}
	return buf;
}

The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.