File 0855-asn1-Fix-several-bugs-in-encoding-and-decoding-of-RE.patch of Package erlang
From 32eda44337cdb591930e66dbd2bbc5931e56263a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 21 Feb 2025 13:25:57 +0100
Subject: [PATCH] asn1: Fix several bugs in encoding and decoding of REALs
Fixes #9096
---
lib/asn1/doc/guides/asn1_getting_started.md | 12 ++++++--
lib/asn1/src/asn1ct_gen_ber_bin_v2.erl | 2 +-
lib/asn1/src/asn1rtt_real_common.erl | 34 ++++++++++-----------
lib/asn1/test/testPrim.erl | 9 +++++-
4 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/lib/asn1/doc/src/asn1_getting_started.xml b/lib/asn1/doc/src/asn1_getting_started.xml
index e9a0d93194..1285943f4c 100644
--- a/lib/asn1/doc/src/asn1_getting_started.xml
+++ b/lib/asn1/doc/src/asn1_getting_started.xml
@@ -475,11 +475,16 @@ R1 ::= REAL</pre>
<p>It is assigned a value in Erlang as follows:</p>
<pre>
R1value1 = "2.14",
-R1value2 = {256,10,-2},</pre>
+R1value2 = {256,10,-2}</pre>
<p>In the last line, notice that the tuple {256,10,-2} is the real number
2.56 in a special notation, which encodes faster than simply
stating the number as <c>"2.56"</c>. The arity three tuple is
- <c>{Mantissa,Base,Exponent}</c>, that is, Mantissa * Base^Exponent.</p>
+ <c>{Mantissa,Base,Exponent}</c>, that is, <c>Mantissa * Base^Exponent</c>.</p>
+ <p>The following special values are also recognized:</p>
+ <pre>
+R1value3 = 0,
+R1value4 = 'PLUS-INFINITY',
+R1value5 = 'MINUS-INFINITY'</pre>
</section>
<section>
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index 79e9c619fa..91e1a8aff6 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -236,7 +236,7 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) ->
asn1ct_name:new(realsize),
emit(["begin",nl,
{curr,realval}," = ",
- {call,real_common,ber_encode_real,[Value]},com,nl,
+ {call,real_common,encode_real,[Value]},com,nl,
{curr,realsize}," = ",
{call,erlang,byte_size,[{curr,realval}]},com,nl,
{call,ber,encode_tags,
diff --git a/lib/asn1/src/asn1rtt_real_common.erl b/lib/asn1/src/asn1rtt_real_common.erl
index 88ad15cf84..ca09af65f0 100644
--- a/lib/asn1/src/asn1rtt_real_common.erl
+++ b/lib/asn1/src/asn1rtt_real_common.erl
@@ -19,8 +19,7 @@
%%
-module(asn1rtt_real_common).
--export([encode_real/1,decode_real/1,
- ber_encode_real/1]).
+-export([encode_real/1,decode_real/1]).
%%============================================================================
%%
@@ -30,14 +29,14 @@
%% encode real value
%%============================================================================
-ber_encode_real(0) ->
- {[],0};
-ber_encode_real('PLUS-INFINITY') ->
- {[64],1};
-ber_encode_real('MINUS-INFINITY') ->
- {[65],1};
-ber_encode_real(Val) when is_tuple(Val); is_list(Val) ->
- encode_real(Val).
+encode_real(0) ->
+ <<>>;
+encode_real('PLUS-INFINITY') ->
+ <<2#0100_0000>>;
+encode_real('MINUS-INFINITY') ->
+ <<2#0100_0001>>;
+encode_real(Val) when is_tuple(Val); is_list(Val) ->
+ encode_real([], Val).
%%%%%%%%%%%%%%
%% only base 2 encoding!
@@ -73,9 +72,6 @@ ber_encode_real(Val) when is_tuple(Val); is_list(Val) ->
%% bit shifted until it is an odd number. Thus, do this for BER as
%% well.
-encode_real(Real) ->
- encode_real([], Real).
-
encode_real(_C, {Mantissa, Base, Exponent}) when Base =:= 2 ->
%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
{Man,ExpAdd} = truncate_zeros(Mantissa), %% DER adjustment
@@ -214,14 +210,16 @@ decode_real(Buffer) ->
{RealVal,<<>>,Sz} = decode_real2(Buffer, [], Sz, 0),
RealVal.
-decode_real2(Buffer, _C, 0, _RemBytes) ->
- {0,Buffer};
+decode_real2(<<>>, _C, 0, _RemBytes) ->
+ {0,<<>>,0};
decode_real2(Buffer0, _C, Len, RemBytes1) ->
<<First, Buffer2/binary>> = Buffer0,
if
- First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
- First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
- First =:= 1 orelse First =:= 2 orelse First =:= 3 ->
+ First =:= 2#01000000 ->
+ {'PLUS-INFINITY', Buffer2, 1};
+ First =:= 2#01000001 ->
+ {'MINUS-INFINITY', Buffer2, 1};
+ First =:= 1; First =:= 2; First =:= 3 ->
%% character string encoding of base 10
{NRx,Rest} = split_binary(Buffer2,Len-1),
{binary_to_list(NRx),Rest,Len};
diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl
index ce7a7f28fa..71049aaeee 100644
--- a/lib/asn1/test/testPrim.erl
+++ b/lib/asn1/test/testPrim.erl
@@ -226,7 +226,14 @@ real(_Rules) ->
%%==========================================================
%% AngleInRadians ::= REAL
%%==========================================================
-
+
+ %% Zero
+ real_roundtrip('AngleInRadians', 0),
+
+ %% Infinities
+ real_roundtrip('AngleInRadians', 'MINUS-INFINITY'),
+ real_roundtrip('AngleInRadians', 'PLUS-INFINITY'),
+
%% Base 2
real_roundtrip('AngleInRadians', {1,2,1}),
real_roundtrip('AngleInRadians', {129,2,1}),
--
2.43.0