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.33';
9 23     23   157 use strict;
  23         49  
  23         793  
10 23     23   126 use Convert::ASN1 qw(:all);
  23         45  
  23         7307  
11 23         3304 use vars qw(
12             $asn $yychar $yyerrflag $yynerrs $yyn @yyss
13             $yyssp $yystate @yyvs $yyvsp $yylval $yys $yym $yyval
14 23     23   167 );
  23         62  
15              
16 23     23   147 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 1472 (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 37 my $op = shift;
74 17         54 my @seq = @$op;
75              
76 17         68 @seq[cTYPE,cCHILD,cVAR,cLOOP] = ('EXPLICIT',[$op],undef,undef);
77 17         48 @{$op}[cTAG,cOPT] = ();
  17         38  
78              
79 17         47 \@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 294 if ($yys = $ENV{'YYDEBUG'})
263             {
264 0 0       0 $yydebug = int($1) if $yys =~ /^(\d)/;
265             }
266              
267              
268 98         160 $yynerrs = 0;
269 98         143 $yyerrflag = 0;
270 98         170 $yychar = (-1);
271              
272 98         148 $yyssp = 0;
273 98         170 $yyvsp = 0;
274 98         195 $yyss[$yyssp] = $yystate = 0;
275              
276 98         164 yyloop: while(1)
277             {
278             yyreduce: {
279 4622 100       5702 last yyreduce if ($yyn = $yydefred[$yystate]);
  4622         9583  
280 2513 100       4271 if ($yychar < 0)
281             {
282 1463 50       2309 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
283             }
284 2513 100 33     13042 if (($yyn = $yysindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      66        
285             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
286             {
287              
288              
289              
290              
291 1365         2272 $yyss[++$yyssp] = $yystate = $yytable[$yyn];
292 1365         2134 $yyvs[++$yyvsp] = $yylval;
293 1365         1750 $yychar = (-1);
294 1365 50       2324 --$yyerrflag if $yyerrflag > 0;
295 1365         2023 next yyloop;
296             }
297 1148 50 33     6044 if (($yyn = $yyrindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      33        
298             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
299             {
300 1148         1618 $yyn = $yytable[$yyn];
301 1148         1653 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         4383 $yym = $yylen[$yyn];
314 3257         5223 $yyval = $yyvs[$yyvsp+1-$yym];
315             switch:
316             {
317 3257         4036 my $label = "State$yyn";
  3257         5260  
318 3257 100       9732 goto $label if exists $yystate{$label};
319 601         929 last switch;
320             State1: {
321             # 107 "parser.y"
322 86         125 { $yyval = { '' => $yyvs[$yyvsp-0] };
  86         112  
  86         266  
323 86         166 last switch;
324             } }
325             State3: {
326             # 112 "parser.y"
327 12         21 {
328 12         29 $yyval = { $yyvs[$yyvsp-2], [$yyvs[$yyvsp-0]] };
  12         56  
329            
330 12         26 last switch;
331             } }
332             State4: {
333             # 116 "parser.y"
334 87         117 {
335 87         108 $yyval=$yyvs[$yyvsp-3];
  87         144  
336 87         328 $yyval->{$yyvs[$yyvsp-2]} = [$yyvs[$yyvsp-0]];
337            
338 87         155 last switch;
339             } }
340             State5: {
341             # 123 "parser.y"
342 99         131 {
343 99         143 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  99         219  
344 99 100       236 $yyval = need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]) ? explicit($yyvs[$yyvsp-1]) : $yyvs[$yyvsp-1];
345            
346 99         205 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         53 {
358 27         37 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  27         79  
359 27         101 @{$yyval = []}[cTYPE,cCHILD,cLOOP,cOPT] = ($yyvs[$yyvsp-5], [$yyvs[$yyvsp-1]], 1, $yyvs[$yyvsp-0]);
  27         101  
360 27 50       116 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
361            
362 27         90 last switch;
363             } }
364             State18: {
365             # 160 "parser.y"
366 49         81 {
367 49         72 @{$yyval = []}[cTYPE,cCHILD] = ('SEQUENCE', $yyvs[$yyvsp-1]);
  49         104  
  49         168  
368            
369 49         93 last switch;
370             } }
371             State19: {
372             # 164 "parser.y"
373 8         13 {
374 8         10 @{$yyval = []}[cTYPE,cCHILD] = ('SET', $yyvs[$yyvsp-1]);
  8         15  
  8         25  
375            
376 8         17 last switch;
377             } }
378             State20: {
379             # 168 "parser.y"
380 14         26 {
381 14         1194 @{$yyval = []}[cTYPE,cCHILD] = ('CHOICE', $yyvs[$yyvsp-1]);
  14         34  
  14         66  
382            
383 14         28 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         390 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  285         358  
  285         559  
  285         965  
395 285         507 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         19 {
410 12         22 @{$yyval = []}[cTYPE,cCHILD,cDEFINE] = ('ANY',undef,$yyvs[$yyvsp-0]);
  12         28  
  12         57  
411            
412 12         26 last switch;
413             } }
414             State26: {
415             # 186 "parser.y"
416 3         4 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  3         6  
  3         6  
  3         10  
417 3         7 last switch;
418             } }
419             State27: {
420             # 189 "parser.y"
421 11         26 { $yyval=undef;
  11         17  
  11         19  
422 11         17 last switch;
423             } }
424             State28: {
425             # 190 "parser.y"
426 1         3 { $yyval=$yyvs[$yyvsp-0];
  1         2  
  1         3  
427 1         1 last switch;
428             } }
429             State30: {
430             # 196 "parser.y"
431 14         25 { $yyval = $yyvs[$yyvsp-0];
  14         27  
  14         30  
432 14         24 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         25 {
442 14         31 $yyval = [ $yyvs[$yyvsp-0] ];
  14         34  
443            
444 14         26 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         44 {
456 28         38 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  28         48  
  28         75  
457            
458 28         49 last switch;
459             } }
460             State35: {
461             # 215 "parser.y"
462 39         64 {
463 39         53 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  39         78  
  39         101  
464 39 50       129 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
465            
466 39         72 last switch;
467             } }
468             State36: {
469             # 220 "parser.y"
470 3         4 {
471 3         6 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  3         4  
  3         10  
472            
473 3         4 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         177 {
483 120         185 my $extension = 0;
  120         217  
484 120         202 $yyval = [];
485 120         223 for my $i (@{$yyvs[$yyvsp-0]}) {
  120         455  
486 218 100       527 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
487 218         463 $i->[cEXT] = $i->[cOPT];
488 218 100       442 $i->[cEXT] = 1 if $extension;
489 218 100       444 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  210         572  
490             }
491 120         234 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  120         255  
492 120 100       248 push @{$yyval}, $e if $extension;
  8         13  
493            
494 120         278 last switch;
495             } }
496             State39: {
497             # 241 "parser.y"
498 23         33 {
499 23         36 my $extension = 0;
  23         51  
500 23         57 $yyval = [];
501 23         44 for my $i (@{$yyvs[$yyvsp-1]}) {
  23         97  
502 23 50       99 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
503 23         64 $i->[cEXT] = $i->[cOPT];
504 23 50       72 $i->[cEXT] = 1 if $extension;
505 23 50       84 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  23         76  
506             }
507 23         42 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  23         45  
508 23 50       76 push @{$yyval}, $e if $extension;
  0         0  
509            
510 23         62 last switch;
511             } }
512             State40: {
513             # 256 "parser.y"
514 143         223 {
515 143         200 $yyval = [ $yyvs[$yyvsp-0] ];
  143         342  
516            
517 143         235 last switch;
518             } }
519             State41: {
520             # 260 "parser.y"
521 98         136 {
522 98         126 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  98         133  
  98         282  
523            
524 98         173 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         319 @{$yyval=$yyvs[$yyvsp-1]}[cOPT] = ($yyvs[$yyvsp-0]);
  202         362  
  202         568  
537            
538 202         391 last switch;
539             } }
540             State47: {
541             # 279 "parser.y"
542 212         286 {
543 212         279 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  212         411  
  212         566  
544 212 100       508 $yyval->[cOPT] = $yyvs[$yyvsp-3] if $yyval->[cOPT];
545 212 100       539 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
546            
547 212         414 last switch;
548             } }
549             State49: {
550             # 286 "parser.y"
551 21         29 {
552 21         40 @{$yyval=$yyvs[$yyvsp-0]}[cTAG] = ($yyvs[$yyvsp-2]);
  21         68  
  21         63  
553 21 50       72 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
554            
555 21         44 last switch;
556             } }
557             State50: {
558             # 291 "parser.y"
559 8         12 {
560 8         11 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  8         11  
  8         23  
561            
562 8         13 last switch;
563             } }
564             State51: {
565             # 296 "parser.y"
566 194         276 { $yyval = undef;
  194         274  
  194         303  
567 194         301 last switch;
568             } }
569             State52: {
570             # 297 "parser.y"
571 35         43 { $yyval = 1;
  35         49  
  35         54  
572 35         55 last switch;
573             } }
574             State53: {
575             # 301 "parser.y"
576 311         404 { $yyval = undef;
  311         619  
  311         466  
577 311         495 last switch;
578             } }
579             State55: {
580             # 305 "parser.y"
581 382         505 { $yyval = undef;
  382         490  
  382         503  
582 382         568 last switch;
583             } }
584             State56: {
585             # 306 "parser.y"
586 11         25 { $yyval = 1;
  11         17  
  11         20  
587 11         18 last switch;
588             } }
589             State57: {
590             # 307 "parser.y"
591 5         8 { $yyval = 0;
  5         5  
  5         8  
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         82 {
612 51         62 last switch;
  51         91  
613             } }
614             State62: {
615             # 318 "parser.y"
616 48         67 {
617 48         63 last switch;
  48         71  
618             } }
619             } # switch
620 3257         4087 $yyssp -= $yym;
621 3257         4262 $yystate = $yyss[$yyssp];
622 3257         3966 $yyvsp -= $yym;
623 3257         4452 $yym = $yylhs[$yyn];
624 3257 100 100     6528 if ($yystate == 0 && $yym == 0)
625             {
626              
627              
628              
629              
630 98         155 $yystate = constYYFINAL();
631 98         181 $yyss[++$yyssp] = constYYFINAL();
632 98         178 $yyvs[++$yyvsp] = $yyval;
633 98 50       248 if ($yychar < 0)
634             {
635 0 0       0 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
636             }
637 98 50       391 return $yyvs[$yyvsp] if $yychar == 0;
638 0         0 next yyloop;
639             }
640 3159 100 100     12743 if (($yyn = $yygindex[$yym]) && ($yyn += $yystate) >= 0 &&
      100        
      100        
641             $yyn <= $#yycheck && $yycheck[$yyn] == $yystate)
642             {
643 1350         2012 $yystate = $yytable[$yyn];
644             } else {
645 1809         2554 $yystate = $yydgoto[$yym];
646             }
647              
648              
649              
650              
651 3159         4647 $yyss[++$yyssp] = $yystate;
652 3159         4846 $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 286 local(*asn) = \($_[0]);
697 98 100       279 $tagdefault = $_[1] eq 'EXPLICIT' ? 1 : 0;
698 98         197 ($pos,$last_pos,@stacked) = ();
699              
700 98         161 eval {
701 98         317 local $SIG{__DIE__};
702 98         267 compile(verify(yyparse()));
703             }
704             }
705              
706             sub compile_one {
707 457     457 0 728 my $tree = shift;
708 457         603 my $ops = shift;
709 457         626 my $name = shift;
710 457         743 foreach my $op (@$ops) {
711 674 100       1410 next unless ref($op) eq 'ARRAY';
712 426         550 bless $op;
713 426         852 my $type = $op->[cTYPE];
714 426 100       848 if (exists $base_type{$type}) {
715 333         624 $op->[cTYPE] = $base_type{$type}->[1];
716 333 100       875 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $base_type{$type}->[0];
717             }
718             else {
719 93 50       179 die "Unknown type '$type'\n" unless exists $tree->{$type};
720             my $ref = compile_one(
721             $tree,
722 93 100       809 $tree->{$type},
723             defined($op->[cVAR]) ? $name . "." . $op->[cVAR] : $name
724             );
725 93 100 100     256 if (defined($op->[cTAG]) && $ref->[0][cTYPE] == opCHOICE) {
726 4         6 @{$op}[cTYPE,cCHILD] = (opSEQUENCE,$ref);
  4         10  
727             }
728             else {
729 89         128 @{$op}[cTYPE,cCHILD,cLOOP] = @{$ref->[0]}[cTYPE,cCHILD,cLOOP];
  89         221  
  89         157  
730             }
731 93 100       252 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $ref->[0][cTAG];
732             }
733 426 100 100     2421 $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       920 if ($op->[cCHILD]) {
737             ;# If we have children we are one of
738             ;# opSET opSEQUENCE opCHOICE opEXPLICIT
739              
740 179 100       924 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     508 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       228 if ( @{$op->[cCHILD]} > 1) {
  179         384  
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       271 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       92 ? (sort map { $_->[cTAG] } $_->[cCHILD])[0]
  0 100       0  
760             : ''
761 8         15 } @{$op->[cCHILD]};
  8         24  
762 8         43 @{$op->[cCHILD]} = @{$op->[cCHILD]}[sort { $tags[$a] cmp $tags[$b] } 0..$#tags];
  8         49  
  8         27  
  31         61  
763             }
764             }
765             else {
766             ;# A SET of one element can be treated the same as a SEQUENCE
767 77 100       181 $op->[cTYPE] = opSEQUENCE if $op->[cTYPE] == opSET;
768             }
769             }
770             }
771 457         961 $ops;
772             }
773              
774             sub compile {
775 98     98 0 159 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         327 while(my($k,$v) = each %$tree) {
789 185         387 compile_one($tree,$v,$k);
790             }
791              
792 98         613 $tree;
793             }
794              
795             sub verify {
796 98 50   98 0 345 my $tree = shift or return;
797 98         197 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         463 while(my($name,$ops) = each %$tree) {
805 185         410 my $stash = {};
806 185         317 my @scope = ();
807 185         275 my $path = "";
808 185         244 my $idx = 0;
809              
810 185         371 while($ops) {
811 726 100       1222 if ($idx < @$ops) {
812 426         664 my $op = $ops->[$idx++];
813 426         529 my $var;
814 426 100       882 if (defined ($var = $op->[cVAR])) {
815            
816             $err .= "$name: $path.$var used multiple times\n"
817 251 50       680 if $stash->{$var}++;
818              
819             }
820 426 100       962 if (defined $op->[cCHILD]) {
821 115 50       236 if (ref $op->[cCHILD]) {
    0          
822 115         267 push @scope, [$stash, $path, $ops, $idx];
823 115 100       260 if (defined $var) {
824 10         35 $stash = {};
825 10         31 $path .= "." . $var;
826             }
827 115         162 $idx = 0;
828 115         257 $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       1084 my $s = pop @scope
840             or last;
841 115         371 ($stash,$path,$ops,$idx) = @$s;
842             }
843             }
844             }
845 98 50       292 die $err if length $err;
846 98         271 $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 2875 return shift @stacked if @stacked;
880              
881 1463         9356 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         5594 ($last_pos,$pos) = ($pos,pos($asn));
912              
913 2841 100       9821 next if defined $1; # comment or whitespace
914              
915 1335 100 100     4141 if (defined $2 or defined $3) {
916 560         974 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       1056 if ($ret eq '}') {
921 71         115 my $p = pos($asn);
922 71         136 my @tmp = @stacked;
923 71         113 @stacked = ();
924 71 50       200 pos($asn) = $p if yylex() != constCOMMA(); # swallow it
925 71         223 @stacked = (@tmp, constPOSTRBRACE());
926             }
927              
928 560         1607 return $reserved{$yylval = $ret};
929             }
930              
931 775 100       1620 if (defined $4) {
932 35         267 ($yylval = $+) =~ s/\s+/_/g;
933 35         103 return constWORD();
934             }
935              
936 740 100       1401 if (defined $5) {
937 642         1145 $yylval = $+;
938 642         1526 return constWORD();
939             }
940              
941 98 100       217 if (defined $6) {
942 87         473 my($class,$num) = ($+ =~ /^([A-Z]*)\s*(\d+)$/);
943 87         330 $yylval = asn_tag($tag_class{$class}, $num);
944 87         224 return constCLASS();
945             }
946              
947 11 50       24 if (defined $7) {
948 0         0 $yylval = $+;
949 0         0 return constNUMBER();
950             }
951              
952 11 50       35 if (defined $8) {
953 11         41 return constEXTENSION_MARKER();
954             }
955              
956 0         0 die "Internal error\n";
957              
958             }
959              
960 128 50       339 die "Parse error before ",substr($asn,$pos,40),"\n"
961             unless $pos == length($asn);
962              
963 128         330 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;