# Buggy code
def addfield(self, pkt, s, i):
    """
    There is a hack with the _ExtensionsField.i2len. It works only because
    we expect _ExtensionsField.i2m to return a string of the same size (if
    not of the same value) upon successive calls (e.g. through i2len here,
    then i2m when directly building the _ExtensionsField).

    XXX A proper way to do this would be to keep the extensions built from
    the i2len call here, instead of rebuilding them later on.
    """
    if i is None:
        if self.length_of is not None:
            fld, fval = pkt.getfield_and_val(self.length_of)

            tmp = pkt.tls_session.frozen
            pkt.tls_session.frozen = True
            f = fld.i2len(pkt, fval)
            pkt.tls_session.frozen = tmp

            i = self.adjust(pkt, f)
            if i == 0:  # for correct build if no ext and not explicitly 0
                v = pkt.tls_session.tls_version
                # Xith TLS 1.3, zero lengths are always explicit.
                if v is None or v < 0x0304:
                    return s
                else:
                    return s + struct.pack(self.fmt, i)
    return s + struct.pack(self.fmt, i)


# Traceback (TypeError)
Traceback (most recent call last):
File "utils/poc.py", line 51, in <module>
test_failed_fn()
File "utils/poc.py", line 47, in test_failed_fn
extract_tls_payloads(os.path.join(data_root, fn), 900)
File "utils/poc.py", line 19, in extract_tls_payloads
payload = bytes(p[TLS])
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/layers/tls/session.py", line 966, in __bytes__
built_packet = super(_GenericTLSSessionInheritance, self).__bytes__()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/packet.py", line 492, in __bytes__
return self.build()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/packet.py", line 612, in build
p = self.do_build()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/packet.py", line 594, in do_build
pkt = self.self_build()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/packet.py", line 575, in self_build
p = f.addfield(self, p, val)
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/layers/tls/record.py", line 207, in addfield
res += self.i2m(pkt, p)
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/layers/tls/record.py", line 194, in i2m
cur = raw(p)
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/compat.py", line 53, in raw
return bytes(x)
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/layers/tls/session.py", line 966, in __bytes__
built_packet = super(_GenericTLSSessionInheritance, self).__bytes__()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/packet.py", line 492, in __bytes__
return self.build()
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/layers/tls/handshake.py", line 1028, in build
m = s.client_random + s.server_random + raw(p)
File "/data1/wangqian/venv_py3/lib/python3.7/site-packages/scapy/compat.py", line 53, in raw
return bytes(x)
TypeError: 'NoneType' object cannot be interpreted as an integer

# Fixed code
def addfield(self, pkt, s, i):
    """
    There is a hack with the _ExtensionsField.i2len. It works only because
    we expect _ExtensionsField.i2m to return a string of the same size (if
    not of the same value) upon successive calls (e.g. through i2len here,
    then i2m when directly building the _ExtensionsField).

    XXX A proper way to do this would be to keep the extensions built from
    the i2len call here, instead of rebuilding them later on.
    """
    if i is None:
        if self.length_of is not None:
            fld, fval = pkt.getfield_and_val(self.length_of)

            tmp = pkt.tls_session.frozen
            pkt.tls_session.frozen = True
            f = fld.i2len(pkt, fval)
            pkt.tls_session.frozen = tmp

            i = self.adjust(pkt, f)
            if i == 0:  # for correct build if no ext and not explicitly 0
                v = pkt.tls_session.tls_version
                # With TLS 1.3, zero lengths are always explicit.
                if v is None or v < 0x0304:
                    return s
                else:
                    return s + struct.pack(self.fmt, i)
    return s + struct.pack(self.fmt, i)