@@ -205,11 +205,7 @@ def __init__(self,
205205 continue
206206 if not isinstance (value , RawVal ):
207207 value = self .get_field (fname ).any2i (self , value )
208-
209- # In case of a list, ensure we store a `list_field` instance, not a simple `list`.
210- if isinstance (value , list ):
211- value = list_field .ensure_bound (self , value )
212-
208+ value = self ._ensure_bound_field_value (value )
213209 self .fields [fname ] = value
214210 # The remaining fields are unknown
215211 for fname in fields :
@@ -219,11 +215,7 @@ def __init__(self,
219215 fname = self ._resolve_alias (fname )
220216 if not isinstance (value , RawVal ):
221217 value = self .get_field (fname ).any2i (self , value )
222-
223- # In case of a list, ensure we store a `list_field` instance, not a simple `list`.
224- if isinstance (value , list ):
225- value = list_field .ensure_bound (self , value )
226-
218+ value = self ._ensure_bound_field_value (value )
227219 self .fields [fname ] = value
228220 continue
229221 raise AttributeError (fname )
@@ -332,10 +324,7 @@ def do_init_cached_fields(self, for_dissect_only=False, init_fields=None):
332324
333325 # Fix: Use `copy_field_value()` instead of just `value.copy()`, in order to duplicate list items as well in case of a list.
334326 self .fields [fname ] = self .copy_field_value (fname , self .default_fields [fname ])
335-
336- # In case of a list, ensure we store a `list_field` instance, not a simple `list`.
337- if isinstance (self .fields [fname ], list ):
338- self .fields [fname ] = list_field .ensure_bound (self , self .fields [fname ])
327+ self .fields [fname ] = self ._ensure_bound_field_value (self .fields [fname ])
339328
340329 self ._ensure_parent_of (self .fields [fname ])
341330
@@ -682,11 +671,7 @@ def setfieldval(self, attr, val):
682671 any2i = fld .any2i
683672 if not isinstance (val , RawVal ):
684673 val = any2i (self , val )
685-
686- # In case of a list, ensure we store a `list_field` instance, not a simple `list`.
687- if isinstance (val , list ):
688- val = list_field .ensure_bound (self , val )
689-
674+ val = self ._ensure_bound_field_value (val )
690675 self .fields [attr ] = val
691676 self .explicit = 0
692677 # Invalidate cache when the packet has changed.
@@ -708,6 +693,31 @@ def __setattr__(self, attr, val):
708693 pass
709694 return object .__setattr__ (self , attr , val )
710695
696+ def _ensure_bound_field_value (
697+ self ,
698+ value , # type: Any
699+ ): # type: (...) -> Any
700+ """
701+ Ensures a field instance bound with ``self`` when applicable.
702+ """
703+ if isinstance (value , list ):
704+ # If `value` is a simple `list`, create a new `list_field` instance.
705+ # If `value` is already a `list_field` instance, we never know where this instance comes from, and what it's being used for.
706+ # Let's create a new `list_field` instance in any case.
707+ return list_field (self , value )
708+
709+ if isinstance (value , FlagValue ):
710+ # We never know where the `FlagValue` instance comes from, and what it's being used for.
711+ # Let's create a new instance.
712+ value = value .copy ()
713+ value .pkt = self
714+ return value
715+
716+ # Non-specific bound field.
717+ # Maybe a packet? rely on parentship in that case.
718+ # Return `value` as is.
719+ return value
720+
711721 def delfieldval (self , attr ):
712722 # type: (str) -> None
713723 if attr in self .fields :
@@ -1233,11 +1243,7 @@ def do_dissect(self, s):
12331243 # Skip unused ConditionalField
12341244 if isinstance (f , ConditionalField ) and fval is None :
12351245 continue
1236-
1237- # In case of a list, ensure we store a `list_field` instance, not a simple `list`.
1238- if isinstance (fval , list ):
1239- fval = list_field .ensure_bound (self , fval )
1240-
1246+ fval = self ._ensure_bound_field_value (fval )
12411247 self .fields [f .name ] = fval
12421248 # Nothing left to dissect
12431249 if not s and (isinstance (f , MayEnd ) or
@@ -2231,19 +2237,6 @@ def __init__(
22312237 #: Packet bound with this list field.
22322238 self .pkt = pkt
22332239
2234- @staticmethod
2235- def ensure_bound (
2236- pkt , # type: Packet
2237- lst , # type: List[Any]
2238- ): # type: (...) -> list_field
2239- """
2240- Ensures a :class:`list_field` instance bound with ``pkt``.
2241- """
2242- # If `lst` is a simple `list`, this method intends to create a new `list_field` instance.
2243- # If `lst` is already a `list_field` instance, we never know where this instance comes from, and what it's being used for.
2244- # Let's create a new `list_field` instance in any case.
2245- return list_field (pkt , lst )
2246-
22472240
22482241####################
22492242# packet classes #
0 commit comments