scapy icon indicating copy to clipboard operation
scapy copied to clipboard

Unexpected behavior when copying FieldContainer

Open wb-airbus opened this issue 1 year ago • 1 comments

Brief description

Copying a FieldContainer instance yields a copy of the contained field instead of the container itself.

This is relevant in cases where a class uses the "field copy" feature in its fields_desc, e.g.:

class A(Packet):
   fields_desc = [ Emph(ByteField("foo", 0)) ]

class B(Packet):
   fields_desc = [ A, ByteField("bar", 0) ]

In this situation, B's foo field should be of type Emph, but it actually is a plain ByteField.

Scapy version

2f3f5dd56bb114b96ce51ce71e2f4ab059b69a42

Python version

3.13.1

Operating system

Linux 6.12.11-200.fc41.x86_64

Additional environment information

No response

How to reproduce

Emph(ByteField("foo", 0)).copy()

Actual result

<ByteField ().foo>

Expected result

# output should be similar to that of
Emph(ByteField("foo", 0))
<scapy.fields.Emph at 0xdeadbeef>

Related resources

No response

wb-airbus avatar Feb 05 '25 13:02 wb-airbus

The following hack makes the copy behave as expected:

from scapy.fields import _FieldContainer
import copy

def _copy_hack(self):
    def maybe_copy_member(m):
        return m.copy() if hasattr(m, "copy") else m

    c = type(self)

    o = c.__new__(c)
    if hasattr(c, "__dict__"):
        o.__dict__ = {
            k: maybe_copy_member(v) for (k, v) in self.__dict__.items()
        }
    if hasattr(c, "__slots__"):
        for s in c.__slots__:
            setattr(o, s, maybe_copy_member(getattr(self, s)))
    return o


_FieldContainer.copy = _copy_hack

wb-airbus avatar Feb 05 '25 13:02 wb-airbus