# Buggy code
def _read_nmap_probes():
    global _NMAP_CUR_PROBE, _NMAP_PROBES_POPULATED
    _NMAP_CUR_PROBE = None

    def parse_line(line):
        global _NMAP_PROBES, _NMAP_CUR_PROBE
        if line.startswith(b"match "):
            line = line[6:]
            soft = False
        elif line.startswith(b"softmatch "):
            line = line[10:]
            soft = True
        elif line.startswith(b"Probe "):
            _NMAP_CUR_PROBE = []
            proto, name, probe = line[6:].split(b" ", 2)
            _NMAP_PROBES.setdefault(proto.lower().decode(), {})[name.decode()] = {
                "probe": probe,
                "fp": _NMAP_CUR_PROBE,
            }
            return
        else:
            return
        service, data = line.split(b" ", 1)
        info = {"soft": soft}
        while data:
            if data.startswith(b"cpe:"):
                key = "cpe"
                data = data[4:]
            else:
                key = data[0:1].decode()
                data = data[1:]
            sep = data[0:1]
            data = data[1:]
            index = data.index(sep)
            value = data[:index]
            data = data[index + 1 :]
            flag = b""
            if data:
                if b" " in data:
                    flag, data = data.split(b" ", 1)
                else:
                    flag, data = data, b""
            if key == "m":
                if value.endswith(b"\\r\\n"):
                    value = value[:-4] + b"(?:\\r\\n|$)"
                elif value.endswith(b"\\\\n"):
                    value = value[:3] + b"(?:\\\\n|$)"
                elif value.endswith(b"\\n"):
                    value = value[:-2] + b"(?:\\n|$)"
                value = re.compile(
                    value,
                    flags=sum(
                        getattr(re, f) if hasattr(re, f) else 0
                        for f in flag.decode().upper()
                    ),
                )
                flag = b""
            else:
                value = value.decode()
            info[key] = (value, flag)
        _NMAP_CUR_PROBE.append((service.decode(), info))

    try:
        with open(
            os.path.join(config.NMAP_SHARE_PATH, "nmap-service-probes"), "rb"
        ) as fdesc:
            for line in fdesc:
                parse_line(line[:-1])
    except (AttributeError, TypeError, IOError):
        LOGGER.warning("Cannot read Nmap service fingerprint file.", exc_info=True)
    del _NMAP_CUR_PROBE
    _NMAP_PROBES_POPULATED = True


# Traceback (UnicodeDecodeError)
user@workstation:~/masscan/bin$ ivre nmap2db --archive --c MASSCAN-BANNER -s SCANNER BANNER.xml
WARNING:ivre:Exception (file 'BANNER.xml')
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/ivre/tools/scan2db.py", line 122, in main
merge=args.merge, masscan_probes=args.masscan_probes,
File "/usr/local/lib/python2.7/dist-packages/ivre/db/__init__.py", line 362, in store_scan
return store_scan_function(fname, filehash=scanid, **kargs)
File "/usr/local/lib/python2.7/dist-packages/ivre/db/__init__.py", line 383, in store_scan_xml
parser.parse(utils.open_file(fname))
File "/usr/lib/python2.7/xml/sax/expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
self.feed(buffer)
File "/usr/lib/python2.7/xml/sax/expatreader.py", line 210, in feed
self._parser.Parse(data, isFinal)
File "/usr/lib/python2.7/xml/sax/expatreader.py", line 304, in start_element
self._cont_handler.startElement(name, AttributesImpl(attrs))
File "/usr/local/lib/python2.7/dist-packages/ivre/xmlnmap.py", line 1109, in startElement
probe=probe,
File "/usr/local/lib/python2.7/dist-packages/ivre/utils.py", line 843, in get_nmap_svc_fp
_read_nmap_probes()
File "/usr/local/lib/python2.7/dist-packages/ivre/utils.py", line 832, in _read_nmap_probes
parse_line(line[:-1])
File "/usr/local/lib/python2.7/dist-packages/ivre/utils.py", line 825, in parse_line
value = value.decode()
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128)
0 results imported.

# Fixed code
def _read_nmap_probes():
    global _NMAP_CUR_PROBE, _NMAP_PROBES_POPULATED
    _NMAP_CUR_PROBE = None

    def parse_line(line):
        global _NMAP_PROBES, _NMAP_CUR_PROBE
        if line.startswith(b"match "):
            line = line[6:]
            soft = False
        elif line.startswith(b"softmatch "):
            line = line[10:]
            soft = True
        elif line.startswith(b"Probe "):
            _NMAP_CUR_PROBE = []
            proto, name, probe = line[6:].split(b" ", 2)
            _NMAP_PROBES.setdefault(proto.lower().decode(), {})[name.decode()] = {
                "probe": probe,
                "fp": _NMAP_CUR_PROBE,
            }
            return
        else:
            return
        service, data = line.split(b" ", 1)
        info = {"soft": soft}
        while data:
            if data.startswith(b"cpe:"):
                key = "cpe"
                data = data[4:]
            else:
                key = data[0:1].decode()
                data = data[1:]
            sep = data[0:1]
            data = data[1:]
            index = data.index(sep)
            value = data[:index]
            data = data[index + 1 :]
            flag = b""
            if data:
                if b" " in data:
                    flag, data = data.split(b" ", 1)
                else:
                    flag, data = data, b""
            if key == "m":
                if value.endswith(b"\\r\\n"):
                    value = value[:-4] + b"(?:\\r\\n|$)"
                elif value.endswith(b"\\\\n"):
                    value = value[:3] + b"(?:\\\\n|$)"
                elif value.endswith(b"\\n"):
                    value = value[:-2] + b"(?:\\n|$)"
                value = re.compile(
                    value,
                    flags=sum(
                        getattr(re, f) if hasattr(re, f) else 0
                        for f in flag.decode().upper()
                    ),
                )
                flag = b""
            else:
                try:
                    value = value.decode("utf-8")
                except UnicodeDecodeError:
                    value = repr(value)
            info[key] = (value, flag)
        _NMAP_CUR_PROBE.append((service.decode(), info))

    try:
        with open(
            os.path.join(config.NMAP_SHARE_PATH, "nmap-service-probes"), "rb"
        ) as fdesc:
            for line in fdesc:
                parse_line(line[:-1])
    except (AttributeError, TypeError, IOError):
        LOGGER.warning("Cannot read Nmap service fingerprint file.", exc_info=True)
    del _NMAP_CUR_PROBE
    _NMAP_PROBES_POPULATED = True