From 82c208f42ba9263cc97e30558dc2564511e64c4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 6 May 2014 11:02:00 +0200
Subject: (U)PER: Fix decoding of named INTEGER

---
 lib/asn1/src/asn1ct_imm.erl                  | 47 ++++++++++++++++++++--------
 lib/asn1/test/asn1_SUITE_data/Constraints.py |  6 ++--
 2 files changed, 38 insertions(+), 15 deletions(-)

(limited to 'lib/asn1')

diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index 5191635a81..bdd14871d1 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -82,15 +82,8 @@ per_dec_enumerated(NamedList0, Aligned) ->
     Ub = length(NamedList0) - 1,
     Constraint = [{'ValueRange',{0,Ub}}],
     Int = per_dec_integer(Constraint, Aligned),
-    EnumTail = case matched_range(Int) of
-		   {0,Ub} ->
-		       %% The error case can never happen.
-		       [];
-		   _ ->
-		       [enum_error]
-	       end,
-    NamedList = per_dec_enumerated_fix_list(NamedList0, EnumTail, 0),
-    {map,Int,NamedList}.
+    NamedList = per_dec_enumerated_fix_list(NamedList0, [enum_error], 0),
+    {map,Int,opt_map(NamedList, Int)}.
 
 per_dec_enumerated(BaseNamedList, NamedListExt0, Aligned) ->
     Base = per_dec_enumerated(BaseNamedList, Aligned),
@@ -124,7 +117,7 @@ per_dec_length(no, AllowZero, Aligned) ->
 per_dec_named_integer(Constraint, NamedList0, Aligned) ->
     Int = per_dec_integer(Constraint, Aligned),
     NamedList = [{K,V} || {V,K} <- NamedList0] ++ [integer_default],
-    {map,Int,NamedList}.
+    {map,Int,opt_map(NamedList, Int)}.
 
 per_dec_k_m_string(StringType, Constraint, Aligned) ->
     SzConstr = effective_constraint(bitstring, Constraint),
@@ -588,14 +581,42 @@ per_num_bits(N) when N =< 64 -> 6;
 per_num_bits(N) when N =< 128 -> 7;
 per_num_bits(N) when N =< 255 -> 8.
 
+opt_map(Map, Imm) ->
+    case matched_range(Imm) of
+	unknown -> Map;
+	{Lb,Ub} -> opt_map_1(Map, Lb, Ub)
+    end.
+
+opt_map_1([{I,_}=Pair|T], Lb, Ub) ->
+    if
+	I =:= Lb, I =< Ub ->
+	    [Pair|opt_map_1(T, Lb+1, Ub)];
+	Lb < I, I =< Ub ->
+	    [Pair|opt_map_1(T, Lb, Ub)];
+	true ->
+	    opt_map_1(T, Lb, Ub)
+    end;
+opt_map_1(Map, Lb, Ub) ->
+    if
+	Lb =< Ub ->
+	    Map;
+	true ->
+	    []
+    end.
+
 matched_range({get_bits,Bits0,[U|Flags]}) when is_integer(U) ->
-    case lists:member(signed, Flags) of
-	false ->
+    case not lists:member(signed, Flags) andalso is_integer(Bits0) of
+	true ->
 	    Bits = U*Bits0,
 	    {0,(1 bsl Bits) - 1};
-	true ->
+	false ->
 	    unknown
     end;
+matched_range({add,Imm,Add}) ->
+    case matched_range(Imm) of
+	unknown -> unknown;
+	{Lb,Ub} -> {Lb+Add,Ub+Add}
+    end;
 matched_range(_Op) -> unknown.
 
 string_num_bits(StringType, Constraint, Aligned) ->
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
index 1fe658d2e2..3495cd841b 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constraints.py
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -66,10 +66,12 @@ Wednesday ::= Day(wednesday)
 
 
 Thing ::= INTEGER {fred (0),fred2 (1),fred3 (2)}
-
-
 AnotherThing ::= Thing (fred | fred2)
 
+OneMoreThing ::= INTEGER {wilma(0), fred(1), betty(3), barney(2)}
+OneMoreThing-1 ::= OneMoreThing (wilma | fred)
+OneMoreThing-2 ::= OneMoreThing (fred | barney)
+
 I ::= INTEGER (0|15..269) -- OTP-5457
 X1 ::= INTEGER (1..4 | 8 | 10 | 20) -- OTP-9946
 
-- 
cgit v1.2.3