@@ -205,11 +205,7 @@ def __init__(self,
205
205
continue
206
206
if not isinstance (value , RawVal ):
207
207
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 )
213
209
self .fields [fname ] = value
214
210
# The remaining fields are unknown
215
211
for fname in fields :
@@ -219,11 +215,7 @@ def __init__(self,
219
215
fname = self ._resolve_alias (fname )
220
216
if not isinstance (value , RawVal ):
221
217
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 )
227
219
self .fields [fname ] = value
228
220
continue
229
221
raise AttributeError (fname )
@@ -332,10 +324,7 @@ def do_init_cached_fields(self, for_dissect_only=False, init_fields=None):
332
324
333
325
# Fix: Use `copy_field_value()` instead of just `value.copy()`, in order to duplicate list items as well in case of a list.
334
326
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 ])
339
328
340
329
self ._ensure_parent_of (self .fields [fname ])
341
330
@@ -682,11 +671,7 @@ def setfieldval(self, attr, val):
682
671
any2i = fld .any2i
683
672
if not isinstance (val , RawVal ):
684
673
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 )
690
675
self .fields [attr ] = val
691
676
self .explicit = 0
692
677
# Invalidate cache when the packet has changed.
@@ -708,6 +693,31 @@ def __setattr__(self, attr, val):
708
693
pass
709
694
return object .__setattr__ (self , attr , val )
710
695
696
+ def _ensure_bound_field_value (
697
+ self ,
698
+ value , # type: Any
699
+ ): # type: (...) -> list_field
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
+
711
721
def delfieldval (self , attr ):
712
722
# type: (str) -> None
713
723
if attr in self .fields :
@@ -1233,11 +1243,7 @@ def do_dissect(self, s):
1233
1243
# Skip unused ConditionalField
1234
1244
if isinstance (f , ConditionalField ) and fval is None :
1235
1245
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 )
1241
1247
self .fields [f .name ] = fval
1242
1248
# Nothing left to dissect
1243
1249
if not s and (isinstance (f , MayEnd ) or
@@ -2231,19 +2237,6 @@ def __init__(
2231
2237
#: Packet bound with this list field.
2232
2238
self .pkt = pkt
2233
2239
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
-
2247
2240
2248
2241
####################
2249
2242
# packet classes #
0 commit comments