# Buggy code
def ParseFileObject(
    self, parser_context, file_object, file_entry=None, parser_chain=None
):
    """Extract data from an *.customDestinations-ms file.

    Args:
      parser_context: A parser context object (instance of ParserContext).
      file_object: A file-like object.
      file_entry: Optional file entry object (instance of dfvfs.FileEntry).
                  The default is None.
      parser_chain: Optional string containing the parsing chain up to this
                    point. The default is None.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    parser_chain = self._BuildParserChain(parser_chain)

    try:
        file_header = self._FILE_HEADER.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        raise errors.UnableToParseFile(
            ("Unable to parse Custom Destination file header with error: {0:s}").format(
                exception
            )
        )

    if file_header.unknown1 != 2:
        raise errors.UnableToParseFile(
            ("Unsupported Custom Destination file - invalid unknown1: {0:d}.").format(
                file_header.unknown1
            )
        )

    if file_header.header_values_type > 2:
        raise errors.UnableToParseFile(
            (
                "Unsupported Custom Destination file - invalid header value type: "
                "{0:d}."
            ).format(file_header.header_values_type)
        )

    if file_header.header_values_type == 0:
        data_structure = self._HEADER_VALUE_TYPE_0
    else:
        data_structure = self._HEADER_VALUE_TYPE_1_OR_2

    try:
        _ = data_structure.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        raise errors.UnableToParseFile(
            (
                "Unable to parse Custom Destination file header value with error: {0:s}"
            ).format(exception)
        )

    file_size = file_object.get_size()
    file_offset = file_object.get_offset()
    remaining_file_size = file_size - file_offset

    # The Custom Destination file does not have a unique signature in
    # the file header that is why we use the first LNK class identifier (GUID)
    # as a signature.
    first_guid_checked = False
    while remaining_file_size > 4:
        try:
            entry_header = self._ENTRY_HEADER.parse_stream(file_object)
        except (IOError, construct.FieldError) as exception:
            if not first_guid_checked:
                raise errors.UnableToParseFile(
                    (
                        "Unable to parse Custom Destination file entry header with "
                        "error: {0:s}"
                    ).format(exception)
                )
            else:
                logging.warning(
                    (
                        "Unable to parse Custom Destination file entry header with "
                        "error: {0:s}"
                    ).format(exception)
                )
            break

        if entry_header.guid != self._LNK_GUID:
            if not first_guid_checked:
                raise errors.UnableToParseFile(
                    "Unsupported Custom Destination file - invalid entry header."
                )
            else:
                logging.warning(
                    "Unsupported Custom Destination file - invalid entry header."
                )
            break

        first_guid_checked = True
        file_offset += 16
        remaining_file_size -= 16

        path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_DATA_RANGE,
            range_offset=file_offset,
            range_size=remaining_file_size,
            parent=file_entry.path_spec,
        )

        lnk_file_object = resolver.Resolver.OpenFileObject(path_spec)

        display_name = "{0:s} # 0x{1:08x}".format(
            parser_context.GetDisplayName(file_entry), file_offset
        )

        self._WINLNK_PARSER.ParseFileObject(
            parser_context,
            lnk_file_object,
            file_entry=file_entry,
            parser_chain=parser_chain,
            display_name=display_name,
        )

        # We cannot trust the file size in the LNK data so we get the last offset
        # that was read instead.
        lnk_file_size = lnk_file_object.get_offset()

        lnk_file_object.close()

        file_offset += lnk_file_size
        remaining_file_size -= lnk_file_size

        file_object.seek(file_offset, os.SEEK_SET)

    try:
        file_footer = self._FILE_FOOTER.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        logging.warning(
            ("Unable to parse Custom Destination file footer with error: {0:s}").format(
                exception
            )
        )

    if file_footer.signature != 0xBABFFBAB:
        logging.warning(
            "Unsupported Custom Destination file - invalid footer signature."
        )


# Traceback (UnicodeDecodeError)
Traceback (most recent call last):
File "build/bdist.linux-x86_64/egg/plaso/engine/worker.py", line 123, in _ParseFileEntryWithParser
parser_object.Parse(self._parser_context, file_entry)
File "build/bdist.linux-x86_64/egg/plaso/parsers/winprefetch.py", line 407, in Parse
filename_strings = self._ParseFilenameStrings(file_object, file_information)
File "build/bdist.linux-x86_64/egg/plaso/parsers/winprefetch.py", line 305, in  _ParseFilenameStrings
filename_strings_data)
File "build/bdist.linux-x86_64/egg/plaso/lib/binary.py", line 243, in   ArrayOfUt16StreamCopyToStringTable
'utf-16-le')
File "/usr/lib/python2.7/encodings/utf_16_le.py", line 16, in decode
return codecs.utf_16_le_decode(input, errors, True)
UnicodeDecodeError: 'utf16' codec can't decode bytes in position 100-101: illegal encoding

# Fixed code
def ParseFileObject(
    self, parser_context, file_object, file_entry=None, parser_chain=None
):
    """Extract data from an *.customDestinations-ms file.

    Args:
      parser_context: A parser context object (instance of ParserContext).
      file_object: A file-like object.
      file_entry: Optional file entry object (instance of dfvfs.FileEntry).
                  The default is None.
      parser_chain: Optional string containing the parsing chain up to this
                    point. The default is None.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    parser_chain = self._BuildParserChain(parser_chain)

    try:
        file_header = self._FILE_HEADER.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        raise errors.UnableToParseFile(
            ("Unable to parse Custom Destination file header with error: {0:s}").format(
                exception
            )
        )

    if file_header.unknown1 != 2:
        raise errors.UnableToParseFile(
            ("Unsupported Custom Destination file - invalid unknown1: {0:d}.").format(
                file_header.unknown1
            )
        )

    if file_header.header_values_type > 2:
        raise errors.UnableToParseFile(
            (
                "Unsupported Custom Destination file - invalid header value type: "
                "{0:d}."
            ).format(file_header.header_values_type)
        )

    if file_header.header_values_type == 0:
        data_structure = self._HEADER_VALUE_TYPE_0
    else:
        data_structure = self._HEADER_VALUE_TYPE_1_OR_2

    try:
        _ = data_structure.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        raise errors.UnableToParseFile(
            (
                "Unable to parse Custom Destination file header value with error: {0:s}"
            ).format(exception)
        )

    file_size = file_object.get_size()
    file_offset = file_object.get_offset()
    remaining_file_size = file_size - file_offset

    # The Custom Destination file does not have a unique signature in
    # the file header that is why we use the first LNK class identifier (GUID)
    # as a signature.
    first_guid_checked = False
    while remaining_file_size > 4:
        try:
            entry_header = self._ENTRY_HEADER.parse_stream(file_object)
        except (IOError, construct.FieldError) as exception:
            if not first_guid_checked:
                raise errors.UnableToParseFile(
                    (
                        "Unable to parse Custom Destination file entry header with "
                        "error: {0:s}"
                    ).format(exception)
                )
            else:
                logging.warning(
                    (
                        "Unable to parse Custom Destination file entry header with "
                        "error: {0:s}"
                    ).format(exception)
                )
            break

        if entry_header.guid != self._LNK_GUID:
            if not first_guid_checked:
                raise errors.UnableToParseFile(
                    "Unsupported Custom Destination file - invalid entry header."
                )
            else:
                logging.warning(
                    "Unsupported Custom Destination file - invalid entry header."
                )
            break

        first_guid_checked = True
        file_offset += 16
        remaining_file_size -= 16

        path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_DATA_RANGE,
            range_offset=file_offset,
            range_size=remaining_file_size,
            parent=file_entry.path_spec,
        )

        try:
            lnk_file_object = resolver.Resolver.OpenFileObject(path_spec)
        except RuntimeError as exception:
            logging.error(
                ("[{0:s}] Unable to open LNK file from {1:s} with error: {2:s}").format(
                    parser_chain,
                    file_entry.path_spec.comparable.replace("\n", ";"),
                    exception,
                )
            )
            return

        display_name = "{0:s} # 0x{1:08x}".format(
            parser_context.GetDisplayName(file_entry), file_offset
        )

        self._WINLNK_PARSER.ParseFileObject(
            parser_context,
            lnk_file_object,
            file_entry=file_entry,
            parser_chain=parser_chain,
            display_name=display_name,
        )

        # We cannot trust the file size in the LNK data so we get the last offset
        # that was read instead.
        lnk_file_size = lnk_file_object.get_offset()

        lnk_file_object.close()

        file_offset += lnk_file_size
        remaining_file_size -= lnk_file_size

        file_object.seek(file_offset, os.SEEK_SET)

    try:
        file_footer = self._FILE_FOOTER.parse_stream(file_object)
    except (IOError, construct.FieldError) as exception:
        logging.warning(
            ("Unable to parse Custom Destination file footer with error: {0:s}").format(
                exception
            )
        )

    if file_footer.signature != 0xBABFFBAB:
        logging.warning(
            "Unsupported Custom Destination file - invalid footer signature."
        )