-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Closed
Description
I have been looking at the internals of FieldListField
and would like to suggest some simple changes.
- Looking at
FieldListField.getfield
, we see that the "internal" representation of this field is a list of internal representations of each element. Therefore the functionFieldListField.i2m
is erroneous: it does not convert the "internal" representation in "machine" representation. - The semantics of
addfield
is that it expects an "internal" representation. Therefore inFieldListField.addfield
the lineval = self.i2m(pkt, val)
can be removed. We should't need to deal with the case whereval
isNone
, because it is an invalid "internal" representation, and havingNone
as the default value is already managed in__init__
.
I also would like to suggest a much more complex change: let's take for example the following piece of code:
class X(Packet):
fields_desc = [ FieldListField("f", [], ByteField("",0)) ]
m = X()
m.f.append(3)
m.show()
assert(repr(m) == "<X |>")
assert(raw(m) == b"\x03")
assert(m.default_fields == {'f': [3]})
assert(m.fields == {})
This is an odd behaviour, because in this case m.f
is m.default_fields['f']
which should not be changed by simple operations. A workaround is to do m.f = m.f
before modifying m.f
but this is not intuitive.
- First proposal: we can note that
m.f
is the "human" representation of the field list, and therefore there is no reason that changing this value should change the content of the packet. Therefore we defineFieldListField.i2h = lambda self, pkt, x: list(x)
. By making a copy we make sure that modifications ofm.f
have no impact onm
(this breaks some non-regression tests). We can even defineFieldListField.i2h = lambda self, pkt, x: tuple(x)
to make it immutable, but it will break more non-regression tests. - Second proposal: use some other type than
list
for the "human" representation, to allow modifications ofm.f
with a sound behaviour. I have begun to work on such an implementation, and I am wondering if others are interested. I prefer this approach because I like when scapy is doing magic, and I can extend this approach to an implementation of HTTP wherep.headers['Content-Type']
can be used to read or write a specific header...