File Coverage

blib/lib/Convert/ASN1/parser.pm
Criterion Covered Total %
statement 337 437 77.1
branch 106 156 67.9
condition 35 68 51.4
subroutine 12 19 63.1
pod 0 14 0.0
total 490 694 70.6


line stmt bran cond sub pod time code
1             #$yysccsid = "@(#)yaccpar 1.8 (Berkeley) 01/20/91 (Perl 2.0 12/31/92)";
2             # 24 "parser.y"
3             ;# Copyright (c) 2000-2005 Graham Barr . All rights reserved.
4             ;# This program is free software; you can redistribute it and/or
5             ;# modify it under the same terms as Perl itself.
6              
7             package Convert::ASN1::parser;
8             $Convert::ASN1::parser::VERSION = '0.34';
9 23     23   167 use strict;
  23         87  
  23         881  
10 23     23   132 use Convert::ASN1 qw(:all);
  23         43  
  23         7775  
11 23         3155 use vars qw(
12             $asn $yychar $yyerrflag $yynerrs $yyn @yyss
13             $yyssp $yystate @yyvs $yyvsp $yylval $yys $yym $yyval
14 23     23   182 );
  23         97  
15              
16 23     23   174 BEGIN { Convert::ASN1->_internal_syms }
17              
18             my $yydebug=0;
19             my %yystate;
20              
21             my %base_type = (
22             BOOLEAN => [ asn_encode_tag(ASN_BOOLEAN), opBOOLEAN ],
23             INTEGER => [ asn_encode_tag(ASN_INTEGER), opINTEGER ],
24             BIT_STRING => [ asn_encode_tag(ASN_BIT_STR), opBITSTR ],
25             OCTET_STRING => [ asn_encode_tag(ASN_OCTET_STR), opSTRING ],
26             STRING => [ asn_encode_tag(ASN_OCTET_STR), opSTRING ],
27             NULL => [ asn_encode_tag(ASN_NULL), opNULL ],
28             OBJECT_IDENTIFIER => [ asn_encode_tag(ASN_OBJECT_ID), opOBJID ],
29             REAL => [ asn_encode_tag(ASN_REAL), opREAL ],
30             ENUMERATED => [ asn_encode_tag(ASN_ENUMERATED), opINTEGER ],
31             ENUM => [ asn_encode_tag(ASN_ENUMERATED), opINTEGER ],
32             'RELATIVE-OID' => [ asn_encode_tag(ASN_RELATIVE_OID), opROID ],
33              
34             SEQUENCE => [ asn_encode_tag(ASN_SEQUENCE | ASN_CONSTRUCTOR), opSEQUENCE ],
35             EXPLICIT => [ asn_encode_tag(ASN_SEQUENCE | ASN_CONSTRUCTOR), opEXPLICIT ],
36             SET => [ asn_encode_tag(ASN_SET | ASN_CONSTRUCTOR), opSET ],
37              
38             ObjectDescriptor => [ asn_encode_tag(ASN_UNIVERSAL | 7), opSTRING ],
39             UTF8String => [ asn_encode_tag(ASN_UNIVERSAL | 12), opUTF8 ],
40             NumericString => [ asn_encode_tag(ASN_UNIVERSAL | 18), opSTRING ],
41             PrintableString => [ asn_encode_tag(ASN_UNIVERSAL | 19), opSTRING ],
42             TeletexString => [ asn_encode_tag(ASN_UNIVERSAL | 20), opSTRING ],
43             T61String => [ asn_encode_tag(ASN_UNIVERSAL | 20), opSTRING ],
44             VideotexString => [ asn_encode_tag(ASN_UNIVERSAL | 21), opSTRING ],
45             IA5String => [ asn_encode_tag(ASN_UNIVERSAL | 22), opSTRING ],
46             UTCTime => [ asn_encode_tag(ASN_UNIVERSAL | 23), opUTIME ],
47             GeneralizedTime => [ asn_encode_tag(ASN_UNIVERSAL | 24), opGTIME ],
48             GraphicString => [ asn_encode_tag(ASN_UNIVERSAL | 25), opSTRING ],
49             VisibleString => [ asn_encode_tag(ASN_UNIVERSAL | 26), opSTRING ],
50             ISO646String => [ asn_encode_tag(ASN_UNIVERSAL | 26), opSTRING ],
51             GeneralString => [ asn_encode_tag(ASN_UNIVERSAL | 27), opSTRING ],
52             CharacterString => [ asn_encode_tag(ASN_UNIVERSAL | 28), opSTRING ],
53             UniversalString => [ asn_encode_tag(ASN_UNIVERSAL | 28), opSTRING ],
54             BMPString => [ asn_encode_tag(ASN_UNIVERSAL | 30), opSTRING ],
55             BCDString => [ asn_encode_tag(ASN_OCTET_STR), opBCD ],
56              
57             CHOICE => [ '', opCHOICE ],
58             ANY => [ '', opANY ],
59              
60             EXTENSION_MARKER => [ '', opEXTENSIONS ],
61             );
62              
63             my $tagdefault = 1; # 0:IMPLICIT , 1:EXPLICIT default
64              
65             ;# args: class,plicit
66             sub need_explicit {
67 398 100   398 0 1428 (defined($_[0]) && (defined($_[1])?$_[1]:$tagdefault));
    100          
68             }
69              
70             ;# Given an OP, wrap it in a SEQUENCE
71              
72             sub explicit {
73 17     17 0 41 my $op = shift;
74 17         66 my @seq = @$op;
75              
76 17         59 @seq[cTYPE,cCHILD,cVAR,cLOOP] = ('EXPLICIT',[$op],undef,undef);
77 17         56 @{$op}[cTAG,cOPT] = ();
  17         36  
78              
79 17         36 \@seq;
80             }
81              
82             sub constWORD () { 1 }
83             sub constCLASS () { 2 }
84             sub constSEQUENCE () { 3 }
85             sub constSET () { 4 }
86             sub constCHOICE () { 5 }
87             sub constOF () { 6 }
88             sub constIMPLICIT () { 7 }
89             sub constEXPLICIT () { 8 }
90             sub constOPTIONAL () { 9 }
91             sub constLBRACE () { 10 }
92             sub constRBRACE () { 11 }
93             sub constCOMMA () { 12 }
94             sub constANY () { 13 }
95             sub constASSIGN () { 14 }
96             sub constNUMBER () { 15 }
97             sub constENUM () { 16 }
98             sub constCOMPONENTS () { 17 }
99             sub constPOSTRBRACE () { 18 }
100             sub constDEFINED () { 19 }
101             sub constBY () { 20 }
102             sub constEXTENSION_MARKER () { 21 }
103             sub constYYERRCODE () { 256 }
104             my @yylhs = ( -1,
105             0, 0, 2, 2, 3, 3, 6, 6, 6, 6,
106             8, 13, 13, 12, 14, 14, 14, 9, 9, 9,
107             10, 18, 18, 18, 18, 18, 19, 19, 11, 16,
108             16, 20, 20, 20, 21, 21, 1, 1, 1, 22,
109             22, 22, 24, 24, 24, 24, 23, 23, 23, 23,
110             15, 15, 4, 4, 5, 5, 5, 17, 17, 25,
111             7, 7,
112             );
113             my @yylen = ( 2,
114             1, 1, 3, 4, 4, 1, 1, 1, 1, 1,
115             3, 1, 1, 6, 1, 1, 1, 4, 4, 4,
116             4, 1, 1, 1, 2, 1, 0, 3, 1, 1,
117             2, 1, 3, 3, 4, 1, 0, 1, 2, 1,
118             3, 3, 2, 1, 1, 1, 4, 1, 3, 1,
119             0, 1, 0, 1, 0, 1, 1, 1, 3, 2,
120             0, 1,
121             );
122             my @yydefred = ( 0,
123             0, 54, 0, 50, 0, 1, 0, 0, 48, 0,
124             40, 0, 0, 0, 0, 57, 56, 0, 0, 0,
125             3, 0, 6, 0, 11, 0, 0, 0, 0, 49,
126             0, 41, 42, 0, 22, 0, 0, 0, 0, 46,
127             44, 0, 45, 0, 29, 47, 4, 0, 0, 0,
128             0, 7, 8, 9, 10, 0, 25, 0, 52, 43,
129             0, 0, 0, 0, 36, 0, 0, 32, 62, 5,
130             0, 0, 0, 58, 0, 18, 19, 0, 20, 0,
131             0, 28, 60, 21, 0, 0, 0, 34, 33, 59,
132             0, 0, 17, 15, 16, 0, 35, 14,
133             );
134             my @yydgoto = ( 5,
135             6, 7, 21, 8, 18, 51, 70, 9, 52, 53,
136             54, 55, 44, 96, 60, 66, 73, 45, 57, 67,
137             68, 10, 11, 46, 74,
138             );
139             my @yysindex = ( 2,
140             58, 0, 8, 0, 0, 0, 11, 123, 0, 3,
141             0, 59, 123, 19, 73, 0, 0, 92, 7, 7,
142             0, 123, 0, 119, 0, 59, 107, 109, 116, 0,
143             82, 0, 0, 119, 0, 107, 109, 84, 126, 0,
144             0, 90, 0, 132, 0, 0, 0, 7, 7, 10,
145             139, 0, 0, 0, 0, 141, 0, 143, 0, 0,
146             82, 156, 159, 82, 0, 160, 4, 0, 0, 0,
147             171, 158, 6, 0, 123, 0, 0, 123, 0, 10,
148             10, 0, 0, 0, 143, 124, 119, 0, 0, 0,
149             107, 109, 0, 0, 0, 90, 0, 0,
150             );
151             my @yyrindex = ( 155,
152             105, 0, 0, 0, 0, 0, 174, 111, 0, 80,
153             0, 105, 138, 0, 0, 0, 0, 0, 161, 145,
154             0, 138, 0, 0, 0, 105, 0, 0, 0, 0,
155             105, 0, 0, 0, 0, 29, 33, 70, 74, 0,
156             0, 46, 0, 0, 0, 0, 0, 45, 45, 0,
157             54, 0, 0, 0, 0, 0, 0, 0, 0, 0,
158             105, 0, 0, 105, 0, 0, 164, 0, 0, 0,
159             0, 0, 0, 0, 138, 0, 0, 138, 0, 0,
160             165, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161             89, 93, 0, 0, 0, 25, 0, 0,
162             );
163             my @yygindex = ( 0,
164             85, 0, 151, 1, -12, 91, 0, 47, -18, -19,
165             -17, 157, 0, 0, 83, 0, 0, 0, 0, 0,
166             -3, 0, 127, 0, 95,
167             );
168             sub constYYTABLESIZE () { 181 }
169             my @yytable = ( 30,
170             24, 13, 1, 2, 41, 40, 42, 31, 2, 34,
171             64, 15, 22, 14, 19, 80, 84, 85, 3, 25,
172             20, 81, 4, 3, 51, 51, 22, 4, 23, 23,
173             65, 13, 24, 24, 12, 51, 51, 23, 13, 23,
174             23, 24, 51, 24, 24, 51, 23, 53, 53, 53,
175             24, 53, 53, 61, 61, 37, 51, 51, 23, 2,
176             2, 75, 86, 51, 78, 87, 94, 93, 95, 27,
177             27, 12, 23, 26, 26, 3, 88, 89, 27, 38,
178             27, 27, 26, 2, 26, 26, 26, 27, 23, 23,
179             38, 26, 24, 24, 27, 28, 29, 23, 59, 23,
180             23, 24, 56, 24, 24, 53, 23, 53, 53, 53,
181             24, 53, 53, 55, 55, 55, 48, 53, 49, 35,
182             53, 36, 37, 29, 35, 50, 91, 92, 29, 16,
183             17, 38, 62, 63, 39, 58, 38, 61, 55, 39,
184             55, 55, 55, 72, 39, 32, 33, 53, 53, 53,
185             55, 53, 53, 55, 37, 39, 69, 53, 53, 53,
186             71, 53, 53, 53, 53, 53, 76, 53, 53, 77,
187             79, 82, 83, 2, 30, 31, 47, 97, 98, 90,
188             43,
189             );
190             my @yycheck = ( 18,
191             13, 1, 1, 2, 24, 24, 24, 1, 2, 22,
192             1, 1, 12, 6, 12, 12, 11, 12, 17, 1,
193             18, 18, 21, 17, 0, 1, 26, 21, 0, 1,
194             21, 31, 0, 1, 6, 11, 12, 9, 6, 11,
195             12, 9, 18, 11, 12, 0, 18, 3, 4, 5,
196             18, 7, 8, 0, 1, 11, 11, 12, 12, 2,
197             2, 61, 75, 18, 64, 78, 86, 86, 86, 0,
198             1, 14, 26, 0, 1, 17, 80, 81, 9, 0,
199             11, 12, 9, 2, 11, 12, 14, 18, 0, 1,
200             11, 18, 0, 1, 3, 4, 5, 9, 9, 11,
201             12, 9, 19, 11, 12, 1, 18, 3, 4, 5,
202             18, 7, 8, 3, 4, 5, 10, 13, 10, 1,
203             16, 3, 4, 5, 1, 10, 3, 4, 5, 7,
204             8, 13, 48, 49, 16, 10, 13, 6, 1, 16,
205             3, 4, 5, 1, 0, 19, 20, 3, 4, 5,
206             13, 7, 8, 16, 0, 11, 18, 3, 4, 5,
207             20, 7, 8, 3, 4, 5, 11, 7, 8, 11,
208             11, 1, 15, 0, 11, 11, 26, 87, 96, 85,
209             24,
210             );
211             sub constYYFINAL () { 5 }
212              
213              
214              
215             sub constYYMAXTOKEN () { 21 }
216 0     0 0 0 sub yyclearin { $yychar = -1; }
217 0     0 0 0 sub yyerrok { $yyerrflag = 0; }
218 0     0 0 0 sub YYERROR { ++$yynerrs; &yy_err_recover; }
  0         0  
219             sub yy_err_recover
220             {
221 0 0   0 0 0 if ($yyerrflag < 3)
222             {
223 0         0 $yyerrflag = 3;
224 0         0 while (1)
225             {
226 0 0 0     0 if (($yyn = $yysindex[$yyss[$yyssp]]) &&
      0        
      0        
227             ($yyn += constYYERRCODE()) >= 0 &&
228             $yyn <= $#yycheck && $yycheck[$yyn] == constYYERRCODE())
229             {
230              
231              
232              
233              
234 0         0 $yyss[++$yyssp] = $yystate = $yytable[$yyn];
235 0         0 $yyvs[++$yyvsp] = $yylval;
236 0         0 next yyloop;
237             }
238             else
239             {
240              
241              
242              
243              
244 0 0       0 return(1) if $yyssp <= 0;
245 0         0 --$yyssp;
246 0         0 --$yyvsp;
247             }
248             }
249             }
250             else
251             {
252 0 0       0 return (1) if $yychar == 0;
253 0         0 $yychar = -1;
254 0         0 next yyloop;
255             }
256 0         0 0;
257             } # yy_err_recover
258              
259             sub yyparse
260             {
261              
262 98 50   98 0 327 if ($yys = $ENV{'YYDEBUG'})
263             {
264 0 0       0 $yydebug = int($1) if $yys =~ /^(\d)/;
265             }
266              
267              
268 98         163 $yynerrs = 0;
269 98         153 $yyerrflag = 0;
270 98         166 $yychar = (-1);
271              
272 98         156 $yyssp = 0;
273 98         156 $yyvsp = 0;
274 98         203 $yyss[$yyssp] = $yystate = 0;
275              
276 98         148 yyloop: while(1)
277             {
278             yyreduce: {
279 4622 100       5619 last yyreduce if ($yyn = $yydefred[$yystate]);
  4622         8254  
280 2513 100       4283 if ($yychar < 0)
281             {
282 1463 50       2334 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
283             }
284 2513 100 33     13205 if (($yyn = $yysindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      66        
285             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
286             {
287              
288              
289              
290              
291 1365         2252 $yyss[++$yyssp] = $yystate = $yytable[$yyn];
292 1365         2094 $yyvs[++$yyvsp] = $yylval;
293 1365         1708 $yychar = (-1);
294 1365 50       2318 --$yyerrflag if $yyerrflag > 0;
295 1365         1997 next yyloop;
296             }
297 1148 50 33     6158 if (($yyn = $yyrindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      33        
298             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
299             {
300 1148         1666 $yyn = $yytable[$yyn];
301 1148         1634 last yyreduce;
302             }
303 0 0       0 if (! $yyerrflag) {
304 0         0 &yyerror('syntax error');
305 0         0 ++$yynerrs;
306             }
307 0 0       0 return undef if &yy_err_recover;
308             } # yyreduce
309              
310              
311              
312              
313 3257         4346 $yym = $yylen[$yyn];
314 3257         5238 $yyval = $yyvs[$yyvsp+1-$yym];
315             switch:
316             {
317 3257         4011 my $label = "State$yyn";
  3257         5164  
318 3257 100       9678 goto $label if exists $yystate{$label};
319 601         867 last switch;
320             State1: {
321             # 107 "parser.y"
322 86         137 { $yyval = { '' => $yyvs[$yyvsp-0] };
  86         121  
  86         256  
323 86         160 last switch;
324             } }
325             State3: {
326             # 112 "parser.y"
327 12         19 {
328 12         27 $yyval = { $yyvs[$yyvsp-2], [$yyvs[$yyvsp-0]] };
  12         69  
329            
330 12         23 last switch;
331             } }
332             State4: {
333             # 116 "parser.y"
334 87         123 {
335 87         107 $yyval=$yyvs[$yyvsp-3];
  87         148  
336 87         393 $yyval->{$yyvs[$yyvsp-2]} = [$yyvs[$yyvsp-0]];
337            
338 87         163 last switch;
339             } }
340             State5: {
341             # 123 "parser.y"
342 99         138 {
343 99         134 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  99         245  
344 99 100       233 $yyval = need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]) ? explicit($yyvs[$yyvsp-1]) : $yyvs[$yyvsp-1];
345            
346 99         220 last switch;
347             } }
348             State11: {
349             # 137 "parser.y"
350 0         0 {
351 0         0 @{$yyval = []}[cTYPE,cCHILD] = ('COMPONENTS', $yyvs[$yyvsp-0]);
  0         0  
  0         0  
352            
353 0         0 last switch;
354             } }
355             State14: {
356             # 147 "parser.y"
357 27         41 {
358 27         38 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  27         71  
359 27         84 @{$yyval = []}[cTYPE,cCHILD,cLOOP,cOPT] = ($yyvs[$yyvsp-5], [$yyvs[$yyvsp-1]], 1, $yyvs[$yyvsp-0]);
  27         113  
360 27 50       108 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
361            
362 27         86 last switch;
363             } }
364             State18: {
365             # 160 "parser.y"
366 49         123 {
367 49         79 @{$yyval = []}[cTYPE,cCHILD] = ('SEQUENCE', $yyvs[$yyvsp-1]);
  49         100  
  49         170  
368            
369 49         135 last switch;
370             } }
371             State19: {
372             # 164 "parser.y"
373 8         13 {
374 8         11 @{$yyval = []}[cTYPE,cCHILD] = ('SET', $yyvs[$yyvsp-1]);
  8         29  
  8         31  
375            
376 8         18 last switch;
377             } }
378             State20: {
379             # 168 "parser.y"
380 14         25 {
381 14         18 @{$yyval = []}[cTYPE,cCHILD] = ('CHOICE', $yyvs[$yyvsp-1]);
  14         35  
  14         58  
382            
383 14         29 last switch;
384             } }
385             State21: {
386             # 174 "parser.y"
387 0         0 {
388 0         0 @{$yyval = []}[cTYPE] = ('ENUM');
  0         0  
  0         0  
389            
390 0         0 last switch;
391             } }
392             State22: {
393             # 179 "parser.y"
394 285         404 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  285         393  
  285         477  
  285         903  
395 285         504 last switch;
396             } }
397             State23: {
398             # 180 "parser.y"
399 0         0 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  0         0  
  0         0  
  0         0  
400 0         0 last switch;
401             } }
402             State24: {
403             # 181 "parser.y"
404 0         0 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  0         0  
  0         0  
  0         0  
405 0         0 last switch;
406             } }
407             State25: {
408             # 183 "parser.y"
409 12         15 {
410 12         28 @{$yyval = []}[cTYPE,cCHILD,cDEFINE] = ('ANY',undef,$yyvs[$yyvsp-0]);
  12         28  
  12         61  
411            
412 12         27 last switch;
413             } }
414             State26: {
415             # 186 "parser.y"
416 3         5 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  3         5  
  3         13  
  3         9  
417 3         7 last switch;
418             } }
419             State27: {
420             # 189 "parser.y"
421 11         39 { $yyval=undef;
  11         13  
  11         21  
422 11         16 last switch;
423             } }
424             State28: {
425             # 190 "parser.y"
426 1         2 { $yyval=$yyvs[$yyvsp-0];
  1         2  
  1         3  
427 1         2 last switch;
428             } }
429             State30: {
430             # 196 "parser.y"
431 14         20 { $yyval = $yyvs[$yyvsp-0];
  14         33  
  14         26  
432 14         22 last switch;
433             } }
434             State31: {
435             # 197 "parser.y"
436 0         0 { $yyval = $yyvs[$yyvsp-1];
  0         0  
  0         0  
437 0         0 last switch;
438             } }
439             State32: {
440             # 201 "parser.y"
441 14         35 {
442 14         39 $yyval = [ $yyvs[$yyvsp-0] ];
  14         38  
443            
444 14         25 last switch;
445             } }
446             State33: {
447             # 205 "parser.y"
448 0         0 {
449 0         0 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  0         0  
  0         0  
450            
451 0         0 last switch;
452             } }
453             State34: {
454             # 209 "parser.y"
455 28         38 {
456 28         38 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  28         36  
  28         78  
457            
458 28         48 last switch;
459             } }
460             State35: {
461             # 215 "parser.y"
462 39         72 {
463 39         49 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  39         71  
  39         102  
464 39 50       119 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
465            
466 39         75 last switch;
467             } }
468             State36: {
469             # 220 "parser.y"
470 3         4 {
471 3         4 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  3         6  
  3         7  
472            
473 3         7 last switch;
474             } }
475             State37: {
476             # 226 "parser.y"
477 0         0 { $yyval = [];
  0         0  
  0         0  
478 0         0 last switch;
479             } }
480             State38: {
481             # 228 "parser.y"
482 120         175 {
483 120         166 my $extension = 0;
  120         210  
484 120         231 $yyval = [];
485 120         222 for my $i (@{$yyvs[$yyvsp-0]}) {
  120         295  
486 218 100       642 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
487 218         462 $i->[cEXT] = $i->[cOPT];
488 218 100       441 $i->[cEXT] = 1 if $extension;
489 218 100       447 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  210         572  
490             }
491 120         225 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  120         244  
492 120 100       248 push @{$yyval}, $e if $extension;
  8         17  
493            
494 120         256 last switch;
495             } }
496             State39: {
497             # 241 "parser.y"
498 23         35 {
499 23         32 my $extension = 0;
  23         58  
500 23         55 $yyval = [];
501 23         43 for my $i (@{$yyvs[$yyvsp-1]}) {
  23         66  
502 23 50       102 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
503 23         61 $i->[cEXT] = $i->[cOPT];
504 23 50       90 $i->[cEXT] = 1 if $extension;
505 23 50       88 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  23         84  
506             }
507 23         73 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  23         57  
508 23 50       81 push @{$yyval}, $e if $extension;
  0         0  
509            
510 23         54 last switch;
511             } }
512             State40: {
513             # 256 "parser.y"
514 143         209 {
515 143         208 $yyval = [ $yyvs[$yyvsp-0] ];
  143         343  
516            
517 143         235 last switch;
518             } }
519             State41: {
520             # 260 "parser.y"
521 98         160 {
522 98         124 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  98         139  
  98         275  
523            
524 98         184 last switch;
525             } }
526             State42: {
527             # 264 "parser.y"
528 0         0 {
529 0         0 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  0         0  
  0         0  
530            
531 0         0 last switch;
532             } }
533             State43: {
534             # 270 "parser.y"
535 202         313 {
536 202         305 @{$yyval=$yyvs[$yyvsp-1]}[cOPT] = ($yyvs[$yyvsp-0]);
  202         383  
  202         540  
537            
538 202         352 last switch;
539             } }
540             State47: {
541             # 279 "parser.y"
542 212         286 {
543 212         284 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  212         404  
  212         595  
544 212 100       490 $yyval->[cOPT] = $yyvs[$yyvsp-3] if $yyval->[cOPT];
545 212 100       524 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
546            
547 212         386 last switch;
548             } }
549             State49: {
550             # 286 "parser.y"
551 21         34 {
552 21         31 @{$yyval=$yyvs[$yyvsp-0]}[cTAG] = ($yyvs[$yyvsp-2]);
  21         57  
  21         66  
553 21 50       79 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
554            
555 21         52 last switch;
556             } }
557             State50: {
558             # 291 "parser.y"
559 8         13 {
560 8         11 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  8         13  
  8         23  
561            
562 8         15 last switch;
563             } }
564             State51: {
565             # 296 "parser.y"
566 194         286 { $yyval = undef;
  194         330  
  194         289  
567 194         304 last switch;
568             } }
569             State52: {
570             # 297 "parser.y"
571 35         48 { $yyval = 1;
  35         47  
  35         51  
572 35         55 last switch;
573             } }
574             State53: {
575             # 301 "parser.y"
576 311         398 { $yyval = undef;
  311         377  
  311         425  
577 311         491 last switch;
578             } }
579             State55: {
580             # 305 "parser.y"
581 382         517 { $yyval = undef;
  382         467  
  382         523  
582 382         556 last switch;
583             } }
584             State56: {
585             # 306 "parser.y"
586 11         23 { $yyval = 1;
  11         18  
  11         20  
587 11         16 last switch;
588             } }
589             State57: {
590             # 307 "parser.y"
591 5         7 { $yyval = 0;
  5         18  
  5         11  
592 5         9 last switch;
593             } }
594             State58: {
595             # 310 "parser.y"
596 0         0 {
597 0         0 last switch;
  0         0  
598             } }
599             State59: {
600             # 311 "parser.y"
601 0         0 {
602 0         0 last switch;
  0         0  
603             } }
604             State60: {
605             # 314 "parser.y"
606 0         0 {
607 0         0 last switch;
  0         0  
608             } }
609             State61: {
610             # 317 "parser.y"
611 51         74 {
612 51         79 last switch;
  51         90  
613             } }
614             State62: {
615             # 318 "parser.y"
616 48         63 {
617 48         77 last switch;
  48         68  
618             } }
619             } # switch
620 3257         4274 $yyssp -= $yym;
621 3257         4195 $yystate = $yyss[$yyssp];
622 3257         3905 $yyvsp -= $yym;
623 3257         4228 $yym = $yylhs[$yyn];
624 3257 100 100     6655 if ($yystate == 0 && $yym == 0)
625             {
626              
627              
628              
629              
630 98         171 $yystate = constYYFINAL();
631 98         179 $yyss[++$yyssp] = constYYFINAL();
632 98         156 $yyvs[++$yyvsp] = $yyval;
633 98 50       263 if ($yychar < 0)
634             {
635 0 0       0 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
636             }
637 98 50       411 return $yyvs[$yyvsp] if $yychar == 0;
638 0         0 next yyloop;
639             }
640 3159 100 100     12693 if (($yyn = $yygindex[$yym]) && ($yyn += $yystate) >= 0 &&
      100        
      100        
641             $yyn <= $#yycheck && $yycheck[$yyn] == $yystate)
642             {
643 1350         2065 $yystate = $yytable[$yyn];
644             } else {
645 1809         2554 $yystate = $yydgoto[$yym];
646             }
647              
648              
649              
650              
651 3159         4533 $yyss[++$yyssp] = $yystate;
652 3159         4473 $yyvs[++$yyvsp] = $yyval;
653             } # yyloop
654             } # yyparse
655             # 322 "parser.y"
656              
657             my %reserved = (
658             'OPTIONAL' => constOPTIONAL(),
659             'CHOICE' => constCHOICE(),
660             'OF' => constOF(),
661             'IMPLICIT' => constIMPLICIT(),
662             'EXPLICIT' => constEXPLICIT(),
663             'SEQUENCE' => constSEQUENCE(),
664             'SET' => constSET(),
665             'ANY' => constANY(),
666             'ENUM' => constENUM(),
667             'ENUMERATED' => constENUM(),
668             'COMPONENTS' => constCOMPONENTS(),
669             '{' => constLBRACE(),
670             '}' => constRBRACE(),
671             ',' => constCOMMA(),
672             '::=' => constASSIGN(),
673             'DEFINED' => constDEFINED(),
674             'BY' => constBY()
675             );
676              
677             my $reserved = join("|", reverse sort grep { /\w/ } keys %reserved);
678              
679             my %tag_class = (
680             APPLICATION => ASN_APPLICATION,
681             UNIVERSAL => ASN_UNIVERSAL,
682             PRIVATE => ASN_PRIVATE,
683             CONTEXT => ASN_CONTEXT,
684             '' => ASN_CONTEXT # if not specified, its CONTEXT
685             );
686              
687             ;##
688             ;## This is NOT thread safe !!!!!!
689             ;##
690              
691             my $pos;
692             my $last_pos;
693             my @stacked;
694              
695             sub parse {
696 98     98 0 285 local(*asn) = \($_[0]);
697 98 100       265 $tagdefault = $_[1] eq 'EXPLICIT' ? 1 : 0;
698 98         193 ($pos,$last_pos,@stacked) = ();
699              
700 98         168 eval {
701 98         327 local $SIG{__DIE__};
702 98         257 compile(verify(yyparse()));
703             }
704             }
705              
706             sub compile_one {
707 457     457 0 698 my $tree = shift;
708 457         599 my $ops = shift;
709 457         604 my $name = shift;
710 457         778 foreach my $op (@$ops) {
711 674 100       1449 next unless ref($op) eq 'ARRAY';
712 426         573 bless $op;
713 426         830 my $type = $op->[cTYPE];
714 426 100       895 if (exists $base_type{$type}) {
715 333         670 $op->[cTYPE] = $base_type{$type}->[1];
716 333 100       844 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $base_type{$type}->[0];
717             }
718             else {
719 93 50       189 die "Unknown type '$type'\n" unless exists $tree->{$type};
720             my $ref = compile_one(
721             $tree,
722 93 100       578 $tree->{$type},
723             defined($op->[cVAR]) ? $name . "." . $op->[cVAR] : $name
724             );
725 93 100 100     244 if (defined($op->[cTAG]) && $ref->[0][cTYPE] == opCHOICE) {
726 4         7 @{$op}[cTYPE,cCHILD] = (opSEQUENCE,$ref);
  4         9  
727             }
728             else {
729 89         129 @{$op}[cTYPE,cCHILD,cLOOP] = @{$ref->[0]}[cTYPE,cCHILD,cLOOP];
  89         260  
  89         161  
730             }
731 93 100       287 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $ref->[0][cTAG];
732             }
733 426 100 100     2223 $op->[cTAG] |= pack("C",ASN_CONSTRUCTOR)
      100        
734             if length $op->[cTAG] && ($op->[cTYPE] == opSET || $op->[cTYPE] == opEXPLICIT || $op->[cTYPE] == opSEQUENCE);
735              
736 426 100       971 if ($op->[cCHILD]) {
737             ;# If we have children we are one of
738             ;# opSET opSEQUENCE opCHOICE opEXPLICIT
739              
740 179 100       910 compile_one($tree, $op->[cCHILD], defined($op->[cVAR]) ? $name . "." . $op->[cVAR] : $name);
741              
742             ;# If a CHOICE is given a tag, then it must be EXPLICIT
743 179 50 66     529 if ($op->[cTYPE] == opCHOICE && defined($op->[cTAG]) && length($op->[cTAG])) {
      66        
744 0         0 $op = bless explicit($op);
745 0         0 $op->[cTYPE] = opSEQUENCE;
746             }
747              
748 179 100       232 if ( @{$op->[cCHILD]} > 1) {
  179         390  
749             ;#if ($op->[cTYPE] != opSEQUENCE) {
750             ;# Here we need to flatten CHOICEs and check that SET and CHOICE
751             ;# do not contain duplicate tags
752             ;#}
753 102 100       279 if ($op->[cTYPE] == opSET) {
754             ;# In case we do CER encoding we order the SET elements by their tags
755             my @tags = map {
756             length($_->[cTAG])
757             ? $_->[cTAG]
758             : $_->[cTYPE] == opCHOICE
759 30 50       102 ? (sort map { $_->[cTAG] } $_->[cCHILD])[0]
  0 100       0  
760             : ''
761 8         13 } @{$op->[cCHILD]};
  8         25  
762 8         55 @{$op->[cCHILD]} = @{$op->[cCHILD]}[sort { $tags[$a] cmp $tags[$b] } 0..$#tags];
  8         43  
  8         33  
  31         56  
763             }
764             }
765             else {
766             ;# A SET of one element can be treated the same as a SEQUENCE
767 77 100       212 $op->[cTYPE] = opSEQUENCE if $op->[cTYPE] == opSET;
768             }
769             }
770             }
771 457         996 $ops;
772             }
773              
774             sub compile {
775 98     98 0 180 my $tree = shift;
776              
777             ;# The tree should be valid enough to be able to
778             ;# - resolve references
779             ;# - encode tags
780             ;# - verify CHOICEs do not contain duplicate tags
781              
782             ;# once references have been resolved, and also due to
783             ;# flattening of COMPONENTS, it is possible for an op
784             ;# to appear in multiple places. So once an op is
785             ;# compiled we bless it. This ensure we don't try to
786             ;# compile it again.
787              
788 98         321 while(my($k,$v) = each %$tree) {
789 185         386 compile_one($tree,$v,$k);
790             }
791              
792 98         650 $tree;
793             }
794              
795             sub verify {
796 98 50   98 0 354 my $tree = shift or return;
797 98         194 my $err = "";
798              
799             ;# Well it parsed correctly, now we
800             ;# - check references exist
801             ;# - flatten COMPONENTS OF (checking for loops)
802             ;# - check for duplicate var names
803              
804 98         531 while(my($name,$ops) = each %$tree) {
805 185         348 my $stash = {};
806 185         286 my @scope = ();
807 185         263 my $path = "";
808 185         257 my $idx = 0;
809              
810 185         413 while($ops) {
811 726 100       1206 if ($idx < @$ops) {
812 426         655 my $op = $ops->[$idx++];
813 426         525 my $var;
814 426 100       892 if (defined ($var = $op->[cVAR])) {
815            
816             $err .= "$name: $path.$var used multiple times\n"
817 251 50       824 if $stash->{$var}++;
818              
819             }
820 426 100       997 if (defined $op->[cCHILD]) {
821 115 50       259 if (ref $op->[cCHILD]) {
    0          
822 115         268 push @scope, [$stash, $path, $ops, $idx];
823 115 100       246 if (defined $var) {
824 10         25 $stash = {};
825 10         37 $path .= "." . $var;
826             }
827 115         167 $idx = 0;
828 115         245 $ops = $op->[cCHILD];
829             }
830             elsif ($op->[cTYPE] eq 'COMPONENTS') {
831 0         0 splice(@$ops,--$idx,1,expand_ops($tree, $op->[cCHILD]));
832             }
833             else {
834 0         0 die "Internal error\n";
835             }
836             }
837             }
838             else {
839 300 100       1286 my $s = pop @scope
840             or last;
841 115         342 ($stash,$path,$ops,$idx) = @$s;
842             }
843             }
844             }
845 98 50       299 die $err if length $err;
846 98         325 $tree;
847             }
848              
849             sub expand_ops {
850 0     0 0 0 my $tree = shift;
851 0         0 my $want = shift;
852 0   0     0 my $seen = shift || { };
853            
854 0 0       0 die "COMPONENTS OF loop $want\n" if $seen->{$want}++;
855 0 0       0 die "Undefined macro $want\n" unless exists $tree->{$want};
856 0         0 my $ops = $tree->{$want};
857 0 0 0     0 die "Bad macro for COMPUNENTS OF '$want'\n"
      0        
      0        
858             unless @$ops == 1
859             && ($ops->[0][cTYPE] eq 'SEQUENCE' || $ops->[0][cTYPE] eq 'SET')
860             && ref $ops->[0][cCHILD];
861 0         0 $ops = $ops->[0][cCHILD];
862 0         0 for(my $idx = 0 ; $idx < @$ops ; ) {
863 0         0 my $op = $ops->[$idx++];
864 0 0       0 if ($op->[cTYPE] eq 'COMPONENTS') {
865 0         0 splice(@$ops,--$idx,1,expand_ops($tree, $op->[cCHILD], $seen));
866             }
867             }
868              
869 0         0 @$ops;
870             }
871              
872             sub _yylex {
873 0     0   0 my $ret = &_yylex;
874 0         0 warn $ret;
875 0         0 $ret;
876             }
877              
878             sub yylex {
879 1534 100   1534 0 2812 return shift @stacked if @stacked;
880              
881 1463         9948 while ($asn =~ /\G(?:
882             (\s+|--[^\n]*)
883             |
884             ([,{}]|::=)
885             |
886             ($reserved)\b
887             |
888             (
889             (?:OCTET|BIT)\s+STRING
890             |
891             OBJECT\s+IDENTIFIER
892             |
893             RELATIVE-OID
894             )\b
895             |
896             (\w+(?:-\w+)*)
897             |
898             \[\s*
899             (
900             (?:(?:APPLICATION|PRIVATE|UNIVERSAL|CONTEXT)\s+)?
901             \d+
902             )
903             \s*\]
904             |
905             \((\d+)\)
906             |
907             (\.\.\.)
908             )/sxgo
909             ) {
910              
911 2841         5180 ($last_pos,$pos) = ($pos,pos($asn));
912              
913 2841 100       8826 next if defined $1; # comment or whitespace
914              
915 1335 100 100     4141 if (defined $2 or defined $3) {
916 560         960 my $ret = $+;
917              
918             # A comma is not required after a '}' so to aid the
919             # parser we insert a fake token after any '}'
920 560 100       1043 if ($ret eq '}') {
921 71         133 my $p = pos($asn);
922 71         140 my @tmp = @stacked;
923 71         111 @stacked = ();
924 71 50       226 pos($asn) = $p if yylex() != constCOMMA(); # swallow it
925 71         257 @stacked = (@tmp, constPOSTRBRACE());
926             }
927              
928 560         1676 return $reserved{$yylval = $ret};
929             }
930              
931 775 100       1601 if (defined $4) {
932 35         218 ($yylval = $+) =~ s/\s+/_/g;
933 35         97 return constWORD();
934             }
935              
936 740 100       1372 if (defined $5) {
937 642         1166 $yylval = $+;
938 642         1517 return constWORD();
939             }
940              
941 98 100       214 if (defined $6) {
942 87         525 my($class,$num) = ($+ =~ /^([A-Z]*)\s*(\d+)$/);
943 87         359 $yylval = asn_tag($tag_class{$class}, $num);
944 87         220 return constCLASS();
945             }
946              
947 11 50       26 if (defined $7) {
948 0         0 $yylval = $+;
949 0         0 return constNUMBER();
950             }
951              
952 11 50       52 if (defined $8) {
953 11         32 return constEXTENSION_MARKER();
954             }
955              
956 0         0 die "Internal error\n";
957              
958             }
959              
960 128 50       401 die "Parse error before ",substr($asn,$pos,40),"\n"
961             unless $pos == length($asn);
962              
963 128         343 0
964             }
965              
966             sub yyerror {
967 0     0 0   die @_," ",substr($asn,$last_pos,40),"\n";
968             }
969              
970             1;
971              
972             %yystate = ('State51','','State34','','State11','','State33','','State24',
973             '','State47','','State40','','State31','','State37','','State23','',
974             'State22','','State21','','State57','','State39','','State56','','State20',
975             '','State25','','State38','','State62','','State14','','State19','',
976             'State5','','State53','','State26','','State27','','State50','','State36',
977             '','State4','','State3','','State32','','State49','','State43','','State30',
978             '','State35','','State52','','State55','','State42','','State28','',
979             'State58','','State61','','State41','','State18','','State59','','State1',
980             '','State60','');
981              
982             1;