Age | Commit message (Collapse) | Author |
|
* bjorn/asn1/fix-extensible-single-values/OTP-11415:
PER/UPER: Correct encoding for single-value extensible constraints
asn1ct_value: Handle named INTEGERs with constraints
|
|
For DER/PER/UPER, a value equal to the DEFAULT is not supposed to
be encoded.
BIT STRINGs values can be represented as Erlang terms in four
different ways: as an integer, as a list of zeroes and ones,
as a {Unused,Binary} tuple, or as an Erlang bitstring.
When encoding a BIT STRING, only certain representations of
BIT STRINGs values were recognized. All representations must
be recognized.
When decoding a DEFAULT value for a BIT STRING, the actual value
given in the decoding would be either an integer or a list
of zeroes and one (depending on how the literal was written in
the specification). We expect that the default value should be
in the same representation as any other BIT STRING value (i.e.
by default an Erlang bitstring, or a list if the 'legacy_bitstring'
option has been given, or as compact bitstring if 'compact_bitstring'
has been given).
|
|
An extensible constraint which is a union of single values, such as:
INTEGER (1|17, ...)
would be incorrectly encoded.
|
|
|
|
The generated code for table constraints has several problems:
* For each object set, a function for getting an encoding or decoding
fun is generated, regardless of whether it is actually used. In many
specifications, the object set actually used is the union of several
other object sets. That means that the code can become a lot bulkier
than it would need to be.
* The funs are not necessary. The funs just add to the code bloat
and generate more unnecessary garbage at run-time. Also, one of
the arguments of the fun is the name of the field in the class which
is known at compile-time, and the fun for decoding has unused arguments.
How to fix the problems:
At each call site where an open type should be encoded/decoded, call a
specific generated function specialized for the actual object set and
the name of the field in the class. When generating the specialized
functions, make sure that we re-use a previously generated function if
possible.
|
|
There are some minor incompatibilities for BIT STRING:
{bit,Position} is now only only supported for a named
BIT STRING type.
Values longer than the maximum size for the BIT STRING type
would be truncated silently - they now cause an exception.
|
|
Break out the the rules for determining whether a string should
be in aligned so that it can be reused for encoding.
|
|
|
|
A semi-constrained INTEGER with a non-zero lower bound would be
incorrectly decoded. This bug was introduced in R16.
|
|
|
|
The encoder wrongly assumed that a known multiplier string (such as
IA5String) encoded as exactly 16 bits did not need to be aligned to an
octet boundary. X.691 (07/2002) 27.5.7 says that it does. Since an
OCTET STRING encoded to 16 bits (two octets) should not be aligned to
an octet boundary, that means that asnct_imm:dec_string() needs an
additional parameter to determine whether a string of a given length
needs to be aligned.
Furthermore, there is another subtle rule difference: An OCTET STRING
which does not have fixed length is always aligned (in PER), but
a known multiplier string is aligned if its upper bound is greater
than or equal to 16.
In encoding, make sure that short known multiplier strings and
OCTET STRINGs with extensible sizes are not aligned when they are
below the appropriate limit.
|
|
Optimize the decoding of CHOICE. Most important is to inline decoding
of the extension bit (if present) and decoding of the choice index
to give the BEAM compiler more opportunities for optimization.
We will also change the structure of the generated code. The current
code uses a flattened case for both the root and extension alternatives:
case Choice + NumRootChoices * Ext of
%% Root alternatives.
0 - ...;
:
LastRootAlternative -> ...;
%% Extension alternatives.
LastRootAlternative+1 -> ...;
:
%% Unknown extension.
_ -> ...;
end
We will instead generate nested cases:
case Ext of
0 ->
case Choice of
%% Root alternatives.
0 - ...;
:
LastRootAlternative -> ...
end;
1 ->
%% Extension alternatives.
<Decode the open type here>
case Choice of
0 -> ...;
:
LastExtensionAlternative -> ...;
%% Unknown extension.
_ -> ...;
end
end
Nested cases should be slightly faster. For decoding of the extensions,
it also makes it possible to hoist the decoding of the open type up
from each case to before the case switching on the extension index,
thus reducing the size of the generated code.
We will also do another change to the structure. Currently, the
big flat clase is wrapped in code that repackages the return values:
{Alt,{Value,RemainingEncodedData}} =
case Choice + NumRootChoices * Ext of
:
end,
{{Value,Alt},RemainingEncodedData}.
We still need to do the repackaging, but we can push it down to
the case arm for decoding each alternative. In many cases, that
will give the BEAM compiler the opportunity to avoid building the
temporary tuples.
|
|
An ENUMERATED with as single value is not encoded. The decoder
incorrectly assumed that it was encoded in one bit.
|
|
|
|
|
|
|
|
|
|
Dialyzer will warn for default clauses that cannot possible match.
|
|
Refactor decoding of BIT STRINGs so that the run-time code does
not spend testing conditions that are known already at compile-time
(which wastes time and produces unnecessary Dialyzer warnings).
There are three ways to decode BIT STRINGs:
1) To a list of bit names (and {bit,Position} for unnamed positions)
if the BIT STRING type has any bit names.
2a) To a list of ones and zeros if there are no named bits, and the
compact_bit_string option was NOT given.
2b) To a {Unused,Bin} tuple if there are no named bits compact_bit_string
option WAS given.
Structure the decoding functions in the same way.
|
|
The template modules (asn1rtt_*.erl) are based on the existing
run-time modules, but with some simplifications and improvements,
for example:
The run-time functions for BER encoding took a Constraint argument which
was not used. It has been eliminated, along with the unused StringType
argument for the encode_restricted_string function.
The Range argument for decode_enumerated() has been dropped since it
was not used.
|
|
|
|
|
|
|
|
|
|
Decoding of fragmented OCTET STRINGs was only implemented when the size
was constrained to a single value. While at it, support decoding
fragmented OCTET STRINGS in all circumstances.
|
|
|