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.32'; # TRIAL
9 23     23   150 use strict;
  23         48  
  23         838  
10 23     23   120 use Convert::ASN1 qw(:all);
  23         46  
  23         7374  
11 23         2859 use vars qw(
12             $asn $yychar $yyerrflag $yynerrs $yyn @yyss
13             $yyssp $yystate @yyvs $yyvsp $yylval $yys $yym $yyval
14 23     23   161 );
  23         58  
15              
16 23     23   153 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 1304 (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 28 my $op = shift;
74 17         47 my @seq = @$op;
75              
76 17         54 @seq[cTYPE,cCHILD,cVAR,cLOOP] = ('EXPLICIT',[$op],undef,undef);
77 17         41 @{$op}[cTAG,cOPT] = ();
  17         32  
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 295 if ($yys = $ENV{'YYDEBUG'})
263             {
264 0 0       0 $yydebug = int($1) if $yys =~ /^(\d)/;
265             }
266              
267              
268 98         158 $yynerrs = 0;
269 98         151 $yyerrflag = 0;
270 98         187 $yychar = (-1);
271              
272 98         144 $yyssp = 0;
273 98         167 $yyvsp = 0;
274 98         209 $yyss[$yyssp] = $yystate = 0;
275              
276 98         149 yyloop: while(1)
277             {
278             yyreduce: {
279 4622 100       5334 last yyreduce if ($yyn = $yydefred[$yystate]);
  4622         7505  
280 2513 100       4066 if ($yychar < 0)
281             {
282 1463 50       2119 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
283             }
284 2513 100 33     11701 if (($yyn = $yysindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      66        
285             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
286             {
287              
288              
289              
290              
291 1365         2113 $yyss[++$yyssp] = $yystate = $yytable[$yyn];
292 1365         1959 $yyvs[++$yyvsp] = $yylval;
293 1365         1634 $yychar = (-1);
294 1365 50       2120 --$yyerrflag if $yyerrflag > 0;
295 1365         1836 next yyloop;
296             }
297 1148 50 33     5449 if (($yyn = $yyrindex[$yystate]) && ($yyn += $yychar) >= 0 &&
      33        
      33        
298             $yyn <= $#yycheck && $yycheck[$yyn] == $yychar)
299             {
300 1148         1506 $yyn = $yytable[$yyn];
301 1148         1537 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         4067 $yym = $yylen[$yyn];
314 3257         4872 $yyval = $yyvs[$yyvsp+1-$yym];
315             switch:
316             {
317 3257         3721 my $label = "State$yyn";
  3257         4967  
318 3257 100       8953 goto $label if exists $yystate{$label};
319 601         785 last switch;
320             State1: {
321             # 107 "parser.y"
322 86         155 { $yyval = { '' => $yyvs[$yyvsp-0] };
  86         120  
  86         259  
323 86         158 last switch;
324             } }
325             State3: {
326             # 112 "parser.y"
327 12         18 {
328 12         21 $yyval = { $yyvs[$yyvsp-2], [$yyvs[$yyvsp-0]] };
  12         48  
329            
330 12         25 last switch;
331             } }
332             State4: {
333             # 116 "parser.y"
334 87         102 {
335 87         94 $yyval=$yyvs[$yyvsp-3];
  87         121  
336 87         295 $yyval->{$yyvs[$yyvsp-2]} = [$yyvs[$yyvsp-0]];
337            
338 87         131 last switch;
339             } }
340             State5: {
341             # 123 "parser.y"
342 99         124 {
343 99         130 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  99         191  
344 99 100       204 $yyval = need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]) ? explicit($yyvs[$yyvsp-1]) : $yyvs[$yyvsp-1];
345            
346 99         162 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         49 {
358 27         36 $yyvs[$yyvsp-1]->[cTAG] = $yyvs[$yyvsp-3];
  27         71  
359 27         81 @{$yyval = []}[cTYPE,cCHILD,cLOOP,cOPT] = ($yyvs[$yyvsp-5], [$yyvs[$yyvsp-1]], 1, $yyvs[$yyvsp-0]);
  27         89  
360 27 50       100 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
361            
362 27         81 last switch;
363             } }
364             State18: {
365             # 160 "parser.y"
366 49         72 {
367 49         64 @{$yyval = []}[cTYPE,cCHILD] = ('SEQUENCE', $yyvs[$yyvsp-1]);
  49         96  
  49         151  
368            
369 49         87 last switch;
370             } }
371             State19: {
372             # 164 "parser.y"
373 8         13 {
374 8         12 @{$yyval = []}[cTYPE,cCHILD] = ('SET', $yyvs[$yyvsp-1]);
  8         22  
  8         28  
375            
376 8         17 last switch;
377             } }
378             State20: {
379             # 168 "parser.y"
380 14         19 {
381 14         17 @{$yyval = []}[cTYPE,cCHILD] = ('CHOICE', $yyvs[$yyvsp-1]);
  14         27  
  14         54  
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         361 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  285         341  
  285         451  
  285         901  
395 285         479 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         13 {
410 12         17 @{$yyval = []}[cTYPE,cCHILD,cDEFINE] = ('ANY',undef,$yyvs[$yyvsp-0]);
  12         23  
  12         47  
411            
412 12         24 last switch;
413             } }
414             State26: {
415             # 186 "parser.y"
416 3         6 { @{$yyval = []}[cTYPE] = $yyvs[$yyvsp-0];
  3         4  
  3         5  
  3         9  
417 3         6 last switch;
418             } }
419             State27: {
420             # 189 "parser.y"
421 11         16 { $yyval=undef;
  11         15  
  11         13  
422 11         17 last switch;
423             } }
424             State28: {
425             # 190 "parser.y"
426 1         2 { $yyval=$yyvs[$yyvsp-0];
  1         3  
  1         3  
427 1         2 last switch;
428             } }
429             State30: {
430             # 196 "parser.y"
431 14         18 { $yyval = $yyvs[$yyvsp-0];
  14         23  
  14         24  
432 14         23 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         21 {
442 14         17 $yyval = [ $yyvs[$yyvsp-0] ];
  14         32  
443            
444 14         22 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         35 {
456 28         32 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  28         38  
  28         66  
457            
458 28         47 last switch;
459             } }
460             State35: {
461             # 215 "parser.y"
462 39         53 {
463 39         43 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  39         67  
  39         84  
464 39 50       113 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
465            
466 39         74 last switch;
467             } }
468             State36: {
469             # 220 "parser.y"
470 3         4 {
471 3         5 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  3         4  
  3         8  
472            
473 3         6 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         173 {
483 120         185 my $extension = 0;
  120         190  
484 120         300 $yyval = [];
485 120         213 for my $i (@{$yyvs[$yyvsp-0]}) {
  120         316  
486 218 100       490 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
487 218         415 $i->[cEXT] = $i->[cOPT];
488 218 100       391 $i->[cEXT] = 1 if $extension;
489 218 100       422 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  210         518  
490             }
491 120         211 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  120         250  
492 120 100       230 push @{$yyval}, $e if $extension;
  8         14  
493            
494 120         254 last switch;
495             } }
496             State39: {
497             # 241 "parser.y"
498 23         38 {
499 23         34 my $extension = 0;
  23         47  
500 23         67 $yyval = [];
501 23         43 for my $i (@{$yyvs[$yyvsp-1]}) {
  23         67  
502 23 50       79 $extension = 1 if $i->[cTYPE] eq 'EXTENSION_MARKER';
503 23         54 $i->[cEXT] = $i->[cOPT];
504 23 50       62 $i->[cEXT] = 1 if $extension;
505 23 50       81 push @{$yyval}, $i unless $i->[cTYPE] eq 'EXTENSION_MARKER';
  23         84  
506             }
507 23         47 my $e = []; $e->[cTYPE] = 'EXTENSION_MARKER';
  23         71  
508 23 50       65 push @{$yyval}, $e if $extension;
  0         0  
509            
510 23         55 last switch;
511             } }
512             State40: {
513             # 256 "parser.y"
514 143         198 {
515 143         186 $yyval = [ $yyvs[$yyvsp-0] ];
  143         313  
516            
517 143         234 last switch;
518             } }
519             State41: {
520             # 260 "parser.y"
521 98         125 {
522 98         119 push @{$yyval=$yyvs[$yyvsp-2]}, $yyvs[$yyvsp-0];
  98         147  
  98         249  
523            
524 98         151 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         296 {
536 202         283 @{$yyval=$yyvs[$yyvsp-1]}[cOPT] = ($yyvs[$yyvsp-0]);
  202         339  
  202         521  
537            
538 202         326 last switch;
539             } }
540             State47: {
541             # 279 "parser.y"
542 212         270 {
543 212         254 @{$yyval=$yyvs[$yyvsp-0]}[cVAR,cTAG] = ($yyvs[$yyvsp-3],$yyvs[$yyvsp-2]);
  212         457  
  212         563  
544 212 100       478 $yyval->[cOPT] = $yyvs[$yyvsp-3] if $yyval->[cOPT];
545 212 100       488 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
546            
547 212         370 last switch;
548             } }
549             State49: {
550             # 286 "parser.y"
551 21         33 {
552 21         31 @{$yyval=$yyvs[$yyvsp-0]}[cTAG] = ($yyvs[$yyvsp-2]);
  21         69  
  21         72  
553 21 50       66 $yyval = explicit($yyval) if need_explicit($yyvs[$yyvsp-2],$yyvs[$yyvsp-1]);
554            
555 21         42 last switch;
556             } }
557             State50: {
558             # 291 "parser.y"
559 8         13 {
560 8         10 @{$yyval=[]}[cTYPE] = 'EXTENSION_MARKER';
  8         12  
  8         25  
561            
562 8         15 last switch;
563             } }
564             State51: {
565             # 296 "parser.y"
566 194         273 { $yyval = undef;
  194         275  
  194         331  
567 194         288 last switch;
568             } }
569             State52: {
570             # 297 "parser.y"
571 35         45 { $yyval = 1;
  35         37  
  35         45  
572 35         45 last switch;
573             } }
574             State53: {
575             # 301 "parser.y"
576 311         381 { $yyval = undef;
  311         365  
  311         398  
577 311         474 last switch;
578             } }
579             State55: {
580             # 305 "parser.y"
581 382         476 { $yyval = undef;
  382         474  
  382         495  
582 382         564 last switch;
583             } }
584             State56: {
585             # 306 "parser.y"
586 11         21 { $yyval = 1;
  11         13  
  11         29  
587 11         15 last switch;
588             } }
589             State57: {
590             # 307 "parser.y"
591 5         8 { $yyval = 0;
  5         6  
  5         8  
592 5         8 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         65 {
612 51         70 last switch;
  51         406  
613             } }
614             State62: {
615             # 318 "parser.y"
616 48         61 {
617 48         54 last switch;
  48         57  
618             } }
619             } # switch
620 3257         3815 $yyssp -= $yym;
621 3257         3893 $yystate = $yyss[$yyssp];
622 3257         3684 $yyvsp -= $yym;
623 3257         3977 $yym = $yylhs[$yyn];
624 3257 100 100     6067 if ($yystate == 0 && $yym == 0)
625             {
626              
627              
628              
629              
630 98         160 $yystate = constYYFINAL();
631 98         171 $yyss[++$yyssp] = constYYFINAL();
632 98         158 $yyvs[++$yyvsp] = $yyval;
633 98 50       245 if ($yychar < 0)
634             {
635 0 0       0 if (($yychar = &yylex) < 0) { $yychar = 0; }
  0         0  
636             }
637 98 50       388 return $yyvs[$yyvsp] if $yychar == 0;
638 0         0 next yyloop;
639             }
640 3159 100 100     11579 if (($yyn = $yygindex[$yym]) && ($yyn += $yystate) >= 0 &&
      100        
      100        
641             $yyn <= $#yycheck && $yycheck[$yyn] == $yystate)
642             {
643 1350         1800 $yystate = $yytable[$yyn];
644             } else {
645 1809         2283 $yystate = $yydgoto[$yym];
646             }
647              
648              
649              
650              
651 3159         4865 $yyss[++$yyssp] = $yystate;
652 3159         4134 $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 295 local(*asn) = \($_[0]);
697 98 100       267 $tagdefault = $_[1] eq 'EXPLICIT' ? 1 : 0;
698 98         248 ($pos,$last_pos,@stacked) = ();
699              
700 98         173 eval {
701 98         318 local $SIG{__DIE__};
702 98         266 compile(verify(yyparse()));
703             }
704             }
705              
706             sub compile_one {
707 457     457 0 618 my $tree = shift;
708 457         562 my $ops = shift;
709 457         561 my $name = shift;
710 457         664 foreach my $op (@$ops) {
711 674 100       1276 next unless ref($op) eq 'ARRAY';
712 426         547 bless $op;
713 426         751 my $type = $op->[cTYPE];
714 426 100       776 if (exists $base_type{$type}) {
715 333         547 $op->[cTYPE] = $base_type{$type}->[1];
716 333 100       783 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $base_type{$type}->[0];
717             }
718             else {
719 93 50       164 die "Unknown type '$type'\n" unless exists $tree->{$type};
720             my $ref = compile_one(
721             $tree,
722 93 100       388 $tree->{$type},
723             defined($op->[cVAR]) ? $name . "." . $op->[cVAR] : $name
724             );
725 93 100 100     229 if (defined($op->[cTAG]) && $ref->[0][cTYPE] == opCHOICE) {
726 4         7 @{$op}[cTYPE,cCHILD] = (opSEQUENCE,$ref);
  4         13  
727             }
728             else {
729 89         110 @{$op}[cTYPE,cCHILD,cLOOP] = @{$ref->[0]}[cTYPE,cCHILD,cLOOP];
  89         218  
  89         148  
730             }
731 93 100       232 $op->[cTAG] = defined($op->[cTAG]) ? asn_encode_tag($op->[cTAG]): $ref->[0][cTAG];
732             }
733 426 100 100     2023 $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       869 if ($op->[cCHILD]) {
737             ;# If we have children we are one of
738             ;# opSET opSEQUENCE opCHOICE opEXPLICIT
739              
740 179 100       1076 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     423 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       214 if ( @{$op->[cCHILD]} > 1) {
  179         362  
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       227 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       94 ? (sort map { $_->[cTAG] } $_->[cCHILD])[0]
  0 100       0  
760             : ''
761 8         15 } @{$op->[cCHILD]};
  8         24  
762 8         51 @{$op->[cCHILD]} = @{$op->[cCHILD]}[sort { $tags[$a] cmp $tags[$b] } 0..$#tags];
  8         36  
  8         26  
  31         61  
763             }
764             }
765             else {
766             ;# A SET of one element can be treated the same as a SEQUENCE
767 77 100       166 $op->[cTYPE] = opSEQUENCE if $op->[cTYPE] == opSET;
768             }
769             }
770             }
771 457         1196 $ops;
772             }
773              
774             sub compile {
775 98     98 0 164 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         375 while(my($k,$v) = each %$tree) {
789 185         382 compile_one($tree,$v,$k);
790             }
791              
792 98         620 $tree;
793             }
794              
795             sub verify {
796 98 50   98 0 347 my $tree = shift or return;
797 98         196 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         457 while(my($name,$ops) = each %$tree) {
805 185         322 my $stash = {};
806 185         285 my @scope = ();
807 185         264 my $path = "";
808 185         247 my $idx = 0;
809              
810 185         356 while($ops) {
811 726 100       1180 if ($idx < @$ops) {
812 426         606 my $op = $ops->[$idx++];
813 426         514 my $var;
814 426 100       809 if (defined ($var = $op->[cVAR])) {
815            
816             $err .= "$name: $path.$var used multiple times\n"
817 251 50       656 if $stash->{$var}++;
818              
819             }
820 426 100       883 if (defined $op->[cCHILD]) {
821 115 50       230 if (ref $op->[cCHILD]) {
    0          
822 115         245 push @scope, [$stash, $path, $ops, $idx];
823 115 100       230 if (defined $var) {
824 10         42 $stash = {};
825 10         26 $path .= "." . $var;
826             }
827 115         143 $idx = 0;
828 115         218 $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       985 my $s = pop @scope
840             or last;
841 115         310 ($stash,$path,$ops,$idx) = @$s;
842             }
843             }
844             }
845 98 50       279 die $err if length $err;
846 98         326 $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 2952 return shift @stacked if @stacked;
880              
881 1463         8652 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         4780 ($last_pos,$pos) = ($pos,pos($asn));
912              
913 2841 100       7953 next if defined $1; # comment or whitespace
914              
915 1335 100 100     3636 if (defined $2 or defined $3) {
916 560         873 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       977 if ($ret eq '}') {
921 71         113 my $p = pos($asn);
922 71         124 my @tmp = @stacked;
923 71         105 @stacked = ();
924 71 50       202 pos($asn) = $p if yylex() != constCOMMA(); # swallow it
925 71         185 @stacked = (@tmp, constPOSTRBRACE());
926             }
927              
928 560         1416 return $reserved{$yylval = $ret};
929             }
930              
931 775 100       1486 if (defined $4) {
932 35         172 ($yylval = $+) =~ s/\s+/_/g;
933 35         87 return constWORD();
934             }
935              
936 740 100       1326 if (defined $5) {
937 642         1061 $yylval = $+;
938 642         1416 return constWORD();
939             }
940              
941 98 100       190 if (defined $6) {
942 87         429 my($class,$num) = ($+ =~ /^([A-Z]*)\s*(\d+)$/);
943 87         296 $yylval = asn_tag($tag_class{$class}, $num);
944 87         210 return constCLASS();
945             }
946              
947 11 50       59 if (defined $7) {
948 0         0 $yylval = $+;
949 0         0 return constNUMBER();
950             }
951              
952 11 50       40 if (defined $8) {
953 11         30 return constEXTENSION_MARKER();
954             }
955              
956 0         0 die "Internal error\n";
957              
958             }
959              
960 128 50       353 die "Parse error before ",substr($asn,$pos,40),"\n"
961             unless $pos == length($asn);
962              
963 128         335 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;