:ref:`context <ctx>` argument to True. Indefinite lengths and
constructed primitive types should be parsed successfully.
-* If object is encoded in BER form (not the DER one), then ``bered``
+* If object is encoded in BER form (not the DER one), then ``ber_encoded``
attribute is set to True. Only ``BOOLEAN``, ``BIT STRING``, ``OCTET
STRING``, ``SEQUENCE``, ``SET``, ``SET OF`` can contain it.
* If object has an indefinite length encoding, then its ``lenindef``
contain it.
* If object has an indefinite length encoded explicit tag, then
``expl_lenindef`` is set to True.
+* If object has either any of BER-related encoding (explicit tag
+ indefinite length, object's indefinite length, BER-encoding) or any
+ underlying component has that kind of encoding, then ``bered``
+ attribute is set to True. For example SignedData CMS can have
+ ``ContentInfo:content:signerInfos:*`` ``bered`` value set to True, but
+ ``ContentInfo:content:signerInfos:*:signedAttrs`` won't.
EOC (end-of-contents) token's length is taken in advance in object's
value length.
"vlen",
"expl_lenindef",
"lenindef",
- "bered",
+ "ber_encoded",
)
def __init__(
self.default = None
self.expl_lenindef = False
self.lenindef = False
- self.bered = False
+ self.ber_encoded = False
@property
def ready(self): # pragma: no cover
"""
raise NotImplementedError()
+ @property
+ def bered(self):
+ """Is either object or any elements inside is BER encoded?
+ """
+ return self.expl_lenindef or self.lenindef or self.ber_encoded
+
def _assert_ready(self):
if not self.ready:
raise ObjNotReady(self.__class__.__name__)
tlen=1,
llen=1,
vlen=0,
+ ber_encoded=True,
bered=True,
)
if self.expl_lenindef:
tlen=1,
llen=1,
vlen=0,
+ ber_encoded=True,
bered=True,
)
"expl_vlen",
"expl_lenindef",
"lenindef",
+ "ber_encoded",
"bered",
))
expl_vlen=None,
expl_lenindef=False,
lenindef=False,
+ ber_encoded=False,
bered=False,
):
return PP(
expl_vlen,
expl_lenindef,
lenindef,
+ ber_encoded,
bered,
)
),
LENINDEF_PP_CHAR if pp.expl_lenindef else " ",
)
- cols.append(_colourize(col, "red", with_colours, ()))
+ col = _colourize(col, "red", with_colours, ())
+ col += _colourize("B", "red", with_colours) if pp.bered else " "
+ cols.append(col)
col = "[%d,%d,%4d]%s" % (
pp.tlen,
pp.llen,
cols.append(_colourize(col, "blue", with_colours))
if pp.asn1_type_name.replace(" ", "") != pp.obj_name.upper():
cols.append(_colourize(pp.obj_name, "magenta", with_colours))
- if pp.bered:
+ if pp.ber_encoded:
cols.append(_colourize("BER", "red", with_colours))
cols.append(_colourize(pp.asn1_type_name, "cyan", with_colours))
if pp.value is not None:
def pp_console_blob(pp, decode_path_len_decrease=0):
- cols = [" " * len("XXXXXYYZ [X,X,XXXX]Z")]
+ cols = [" " * len("XXXXXYYZZ [X,X,XXXX]Z")]
decode_path_len = len(pp.decode_path) - decode_path_len_decrease
if decode_path_len > 0:
cols.append(" ." * (decode_path_len + 1))
offset=offset,
)
first_octet = byte2int(v)
- bered = False
+ ber_encoded = False
if first_octet == 0:
value = False
elif first_octet == 0xFF:
value = True
elif ctx.get("bered", False):
value = True
- bered = True
+ ber_encoded = True
else:
raise DecodeError(
"unacceptable Boolean value",
optional=self.optional,
_decoded=(offset, 1, 1),
)
- obj.bered = bered
+ obj.ber_encoded = ber_encoded
return obj, v[1:]
def __repr__(self):
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ ber_encoded=self.ber_encoded,
bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
yield pp
_decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)),
)
obj.lenindef = lenindef
- obj.bered = True
+ obj.ber_encoded = True
return obj, (v[EOC_LEN:] if lenindef else v)
raise TagMismatch(
klass=self.__class__,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
bered=self.bered,
)
defined_by, defined = self.defined or (None, None)
offset=offset,
)
obj.lenindef = lenindef
- obj.bered = True
+ obj.ber_encoded = True
return obj, (v[EOC_LEN:] if lenindef else v)
raise TagMismatch(
klass=self.__class__,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
bered=self.bered,
)
defined_by, defined = self.defined or (None, None)
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
yield pp
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
yield pp
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
yield pp
expl_llen=self.expl_llen if self.expled else None,
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
)
for pp in self.pps_lenindef(decode_path):
yield pp
def ready(self):
return self._value is not None and self._value[1].ready
+ @property
+ def bered(self):
+ return self.expl_lenindef or (
+ (self._value is not None) and
+ self._value[1].bered
+ )
+
def copy(self):
obj = self.__class__(schema=self.specs)
obj._expl = self._expl
_decoded=(offset, 0, value.fulllen),
)
obj._value = (choice, value)
+ obj.lenindef = value.lenindef
+ obj.ber_encoded = value.ber_encoded
return obj, tail
def __repr__(self):
llen=self.llen,
vlen=self.vlen,
expl_lenindef=self.expl_lenindef,
+ lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
)
if self.ready:
yield self.value.pps(decode_path=decode_path + (self.choice,))
def ready(self):
return self._value is not None
+ @property
+ def bered(self):
+ if self.expl_lenindef or self.lenindef:
+ return True
+ if self.defined is None:
+ return False
+ return self.defined[1].bered
+
def copy(self):
obj = self.__class__()
obj._value = self._value
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
lenindef=self.lenindef,
+ bered=self.bered,
)
defined_by, defined = self.defined or (None, None)
if defined_by is not None:
return False
return True
+ @property
+ def bered(self):
+ if self.expl_lenindef or self.lenindef or self.ber_encoded:
+ return True
+ return any(value.bered for value in self._value.values())
+
def copy(self):
obj = self.__class__(schema=self.specs)
obj.tag = self.tag
vlen = 0
sub_offset = offset + tlen + llen
values = {}
- bered = False
+ ber_encoded = False
ctx_allow_default_values = ctx.get("allow_default_values", False)
for name, spec in self.specs.items():
if spec.optional and (
v = v_tail
if spec.default is not None and value == spec.default:
if ctx_bered or ctx_allow_default_values:
- bered = True
+ ber_encoded = True
else:
raise DecodeError(
"DEFAULT value met",
)
obj._value = values
obj.lenindef = lenindef
- obj.bered = bered
+ obj.ber_encoded = ber_encoded
return obj, tail
def __repr__(self):
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
)
for name in self.specs:
value = self._value.get(name)
vlen = 0
sub_offset = offset + tlen + llen
values = {}
- bered = False
+ ber_encoded = False
ctx_allow_default_values = ctx.get("allow_default_values", False)
ctx_allow_unordered_set = ctx.get("allow_unordered_set", False)
value_prev = memoryview(v[:0])
value_len = value.fulllen
if value_prev.tobytes() > v[:value_len].tobytes():
if ctx_bered or ctx_allow_unordered_set:
- bered = True
+ ber_encoded = True
else:
raise DecodeError(
"unordered " + self.asn1_type_name,
if spec.default is None or value != spec.default:
pass
elif ctx_bered or ctx_allow_default_values:
- bered = True
+ ber_encoded = True
else:
raise DecodeError(
"DEFAULT value met",
decode_path=decode_path,
offset=offset,
)
- obj.bered = bered
+ obj.ber_encoded = ber_encoded
return obj, tail
def ready(self):
return all(v.ready for v in self._value)
+ @property
+ def bered(self):
+ if self.expl_lenindef or self.lenindef or self.ber_encoded:
+ return True
+ return any(v.bered for v in self._value)
+
def copy(self):
obj = self.__class__(schema=self.spec)
obj._bound_min = self._bound_min
_value = []
ctx_allow_unordered_set = ctx.get("allow_unordered_set", False)
value_prev = memoryview(v[:0])
- bered = False
+ ber_encoded = False
spec = self.spec
while len(v) > 0:
if lenindef and v[:EOC_LEN].tobytes() == EOC:
if ordering_check:
if value_prev.tobytes() > v[:value_len].tobytes():
if ctx_bered or ctx_allow_unordered_set:
- bered = True
+ ber_encoded = True
else:
raise DecodeError(
"unordered " + self.asn1_type_name,
)
obj.lenindef = True
tail = v[EOC_LEN:]
- obj.bered = bered
+ obj.ber_encoded = ber_encoded
return obj, tail
def __repr__(self):
expl_vlen=self.expl_vlen if self.expled else None,
expl_lenindef=self.expl_lenindef,
lenindef=self.lenindef,
+ ber_encoded=self.ber_encoded,
+ bered=self.bered,
)
for i, value in enumerate(self._value):
yield value.pps(decode_path=decode_path + (str(i),))