1*2c53affbSjmc /* $OpenBSD: keynote.y,v 1.19 2022/12/27 17:10:06 jmc Exp $ */
2983e9580Sangelos /*
3983e9580Sangelos * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
4983e9580Sangelos *
5983e9580Sangelos * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
6983e9580Sangelos * in April-May 1998
7983e9580Sangelos *
8983e9580Sangelos * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
9983e9580Sangelos *
105e4ac158Sderaadt * Permission to use, copy, and modify this software with or without fee
11983e9580Sangelos * is hereby granted, provided that this entire notice is included in
12983e9580Sangelos * all copies of any software which is or includes a copy or
13983e9580Sangelos * modification of this software.
14983e9580Sangelos *
15983e9580Sangelos * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
16983e9580Sangelos * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
17983e9580Sangelos * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
18983e9580Sangelos * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
19983e9580Sangelos * PURPOSE.
20983e9580Sangelos */
21983e9580Sangelos %union {
22983e9580Sangelos char *string;
23983e9580Sangelos double doubval;
24983e9580Sangelos int intval;
25983e9580Sangelos int bool;
26983e9580Sangelos };
27983e9580Sangelos %type <bool> stringexp numexp expr floatexp
28983e9580Sangelos %type <intval> NUM KOF numex afterhint notemptyprog
29983e9580Sangelos %type <intval> notemptykeypredicate prog key keyexp keylist
30983e9580Sangelos %type <doubval> FLOAT floatex
31983e9580Sangelos %type <string> STRING VARIABLE str strnotconcat
32983e9580Sangelos %token TRUE FALSE NUM FLOAT STRING VARIABLE
33983e9580Sangelos %token OPENPAREN CLOSEPAREN EQQ COMMA ACTSTR LOCINI KOF KEYPRE KNVERSION
34983e9580Sangelos %token DOTT SIGNERKEY HINT OPENBLOCK CLOSEBLOCK SIGNATUREENTRY PRIVATEKEY
35983e9580Sangelos %token SEMICOLON TRUE FALSE
36983e9580Sangelos %nonassoc EQ NE LT GT LE GE REGEXP
37983e9580Sangelos %left OR
38983e9580Sangelos %left AND
39983e9580Sangelos %right NOT
40983e9580Sangelos %left PLUS MINUS DOTT
41983e9580Sangelos %left MULT DIV MOD
42983e9580Sangelos %left EXP
43983e9580Sangelos %nonassoc UNARYMINUS DEREF OPENNUM OPENFLT
44983e9580Sangelos %start grammarswitch
45983e9580Sangelos %{
46983e9580Sangelos #include <sys/types.h>
47e0758482Smsf
48983e9580Sangelos #include <ctype.h>
499186b70cSangelos #include <math.h>
5085616838Smsf #include <regex.h>
51e0758482Smsf #include <stdio.h>
52e0758482Smsf #include <stdlib.h>
539186b70cSangelos #include <string.h>
54a8a6ad51Sangelos
55a8a6ad51Sangelos #include "keynote.h"
56a8a6ad51Sangelos #include "assertion.h"
57983e9580Sangelos
58313d0fe7Smmcc static int *keynote_kth_array = NULL;
59983e9580Sangelos static int keylistcount = 0;
60983e9580Sangelos
61983e9580Sangelos static int resolve_assertion(char *);
62983e9580Sangelos static int keynote_init_kth(void);
63983e9580Sangelos static int isfloatstring(char *);
64983e9580Sangelos static int checkexception(int);
65983e9580Sangelos static char *my_lookup(char *);
66983e9580Sangelos static int intpow(int, int);
67983e9580Sangelos static int get_kth(int);
68983e9580Sangelos %}
69983e9580Sangelos %%
70983e9580Sangelos
71983e9580Sangelos grammarswitch: LOCINI { keynote_exceptionflag = keynote_donteval = 0; }
72983e9580Sangelos localinit
73983e9580Sangelos | ACTSTR { keynote_exceptionflag = keynote_donteval = 0; } program
74983e9580Sangelos | KEYPRE { keynote_exceptionflag = keynote_donteval = 0; }
75983e9580Sangelos keypredicate
76983e9580Sangelos | SIGNERKEY { keynote_exceptionflag = keynote_donteval = 0; } key
77983e9580Sangelos | SIGNATUREENTRY { keynote_exceptionflag = keynote_donteval = 0; }
78983e9580Sangelos key
79983e9580Sangelos | KNVERSION { keynote_exceptionflag = keynote_donteval = 0; }
80983e9580Sangelos STRING { keynote_lex_remove($3);
81983e9580Sangelos if (strcmp($3, KEYNOTE_VERSION_STRING))
82983e9580Sangelos keynote_errno = ERROR_SYNTAX;
83983e9580Sangelos free($3);
84983e9580Sangelos }
85983e9580Sangelos | PRIVATEKEY { keynote_exceptionflag = keynote_donteval = 0; }
86983e9580Sangelos STRING { keynote_lex_remove($3);
87983e9580Sangelos keynote_privkey = $3;
88983e9580Sangelos }
89983e9580Sangelos
90983e9580Sangelos keypredicate: /* Nothing */ { keynote_returnvalue = 0;
91983e9580Sangelos return 0;
92983e9580Sangelos }
93983e9580Sangelos | notemptykeypredicate { keynote_returnvalue = $1;
94983e9580Sangelos return 0;
95983e9580Sangelos }
96983e9580Sangelos
97983e9580Sangelos notemptykeypredicate: key { $$ = $1; }
98983e9580Sangelos | keyexp { $$ = $1; }
99983e9580Sangelos
100983e9580Sangelos keyexp: notemptykeypredicate AND { if (($1 == 0) && !keynote_justrecord)
101983e9580Sangelos keynote_donteval = 1;
102983e9580Sangelos } notemptykeypredicate
103983e9580Sangelos { if ($1 > $4)
104983e9580Sangelos $$ = $4;
105983e9580Sangelos else
106983e9580Sangelos $$ = $1;
107983e9580Sangelos keynote_donteval = 0;
108983e9580Sangelos } /* Min */
109983e9580Sangelos | notemptykeypredicate OR { if (($1 == (keynote_current_session->ks_values_num - 1)) && !keynote_justrecord)
110983e9580Sangelos keynote_donteval = 1;
111983e9580Sangelos } notemptykeypredicate
112983e9580Sangelos { if ($1 >= $4)
113983e9580Sangelos $$ = $1;
114983e9580Sangelos else
115983e9580Sangelos $$ = $4;
116983e9580Sangelos keynote_donteval = 0;
117983e9580Sangelos } /* Max */
118983e9580Sangelos | OPENPAREN keyexp CLOSEPAREN { $$ = $2; }
119983e9580Sangelos | KOF { keylistcount = 0; } OPENPAREN {
120983e9580Sangelos if (!keynote_justrecord && !keynote_donteval)
121983e9580Sangelos if (keynote_init_kth() == -1)
122983e9580Sangelos return -1;
123983e9580Sangelos } keylist CLOSEPAREN
124983e9580Sangelos {
125983e9580Sangelos if (keylistcount < $1)
126983e9580Sangelos {
127983e9580Sangelos keynote_errno = ERROR_SYNTAX;
128983e9580Sangelos return -1;
129983e9580Sangelos }
130983e9580Sangelos
131983e9580Sangelos if (!keynote_justrecord && !keynote_donteval)
132983e9580Sangelos $$ = get_kth($1);
133983e9580Sangelos else
134983e9580Sangelos $$ = 0;
135983e9580Sangelos } /* K-th */
136983e9580Sangelos
137983e9580Sangelos keylist: key
138983e9580Sangelos { /* Don't do anything if we're just recording */
139983e9580Sangelos if (!keynote_justrecord && !keynote_donteval)
140983e9580Sangelos if (($1 < keynote_current_session->ks_values_num) && ($1 >= 0))
141983e9580Sangelos keynote_kth_array[$1]++;
142983e9580Sangelos
143983e9580Sangelos keylistcount++;
144983e9580Sangelos }
145983e9580Sangelos | key COMMA keylist
146983e9580Sangelos { /* Don't do anything if we're just recording */
147983e9580Sangelos if (!keynote_justrecord && !keynote_donteval)
148983e9580Sangelos if (($1 < keynote_current_session->ks_values_num) && ($1 >= 0))
149983e9580Sangelos keynote_kth_array[$1]++;
150983e9580Sangelos
151983e9580Sangelos keylistcount++;
152983e9580Sangelos }
153983e9580Sangelos
154983e9580Sangelos key: str {
155983e9580Sangelos if (keynote_donteval)
156983e9580Sangelos $$ = 0;
157983e9580Sangelos else
158983e9580Sangelos {
159983e9580Sangelos keynote_lex_remove($1);
160983e9580Sangelos if (keynote_justrecord)
161983e9580Sangelos {
162983e9580Sangelos if (keynote_keylist_add(&keynote_keypred_keylist,
163983e9580Sangelos $1) == -1)
164983e9580Sangelos {
165983e9580Sangelos free($1);
166983e9580Sangelos return -1;
167983e9580Sangelos }
168983e9580Sangelos
169983e9580Sangelos $$ = 0;
170983e9580Sangelos }
171983e9580Sangelos else
172983e9580Sangelos switch (keynote_in_action_authorizers($1, KEYNOTE_ALGORITHM_UNSPEC))
173983e9580Sangelos {
174983e9580Sangelos case -1:
175983e9580Sangelos free($1);
176983e9580Sangelos return -1;
177983e9580Sangelos
178983e9580Sangelos case RESULT_TRUE:
179983e9580Sangelos free($1);
180983e9580Sangelos $$ = keynote_current_session->ks_values_num -
181983e9580Sangelos 1;
182983e9580Sangelos break;
183983e9580Sangelos
184983e9580Sangelos default:
185983e9580Sangelos $$ = resolve_assertion($1);
186983e9580Sangelos free($1);
187983e9580Sangelos break;
188983e9580Sangelos }
189983e9580Sangelos }
190983e9580Sangelos }
191983e9580Sangelos
192983e9580Sangelos localinit: /* Nothing */
193983e9580Sangelos | localconstants
194983e9580Sangelos
195983e9580Sangelos localconstants: VARIABLE EQQ STRING
196983e9580Sangelos {
197983e9580Sangelos int i;
198983e9580Sangelos
199983e9580Sangelos keynote_lex_remove($1);
200983e9580Sangelos keynote_lex_remove($3);
201983e9580Sangelos
202983e9580Sangelos /*
203983e9580Sangelos * Variable names starting with underscores are illegal here.
204983e9580Sangelos */
205983e9580Sangelos if ($1[0] == '_')
206983e9580Sangelos {
207983e9580Sangelos free($1);
208983e9580Sangelos free($3);
209983e9580Sangelos keynote_errno = ERROR_SYNTAX;
210983e9580Sangelos return -1;
211983e9580Sangelos }
212983e9580Sangelos
213983e9580Sangelos /* If the identifier already exists, report error. */
214313d0fe7Smmcc if (keynote_env_lookup($1, &keynote_init_list, 1) != NULL)
215983e9580Sangelos {
216983e9580Sangelos free($1);
217983e9580Sangelos free($3);
218983e9580Sangelos keynote_errno = ERROR_SYNTAX;
219983e9580Sangelos return -1;
220983e9580Sangelos }
221983e9580Sangelos
222983e9580Sangelos i = keynote_env_add($1, $3, &keynote_init_list, 1, 0);
223983e9580Sangelos free($1);
224983e9580Sangelos free($3);
225983e9580Sangelos
226983e9580Sangelos if (i != RESULT_TRUE)
227983e9580Sangelos return -1;
228983e9580Sangelos }
229983e9580Sangelos | VARIABLE EQQ STRING
230983e9580Sangelos {
231983e9580Sangelos int i;
232983e9580Sangelos
233983e9580Sangelos keynote_lex_remove($1);
234983e9580Sangelos keynote_lex_remove($3);
235983e9580Sangelos
236983e9580Sangelos /*
237983e9580Sangelos * Variable names starting with underscores are illegal here.
238983e9580Sangelos */
239983e9580Sangelos if ($1[0] == '_')
240983e9580Sangelos {
241983e9580Sangelos free($1);
242983e9580Sangelos free($3);
243983e9580Sangelos keynote_errno = ERROR_SYNTAX;
244983e9580Sangelos return -1;
245983e9580Sangelos }
246983e9580Sangelos
247983e9580Sangelos /* If the identifier already exists, report error. */
248313d0fe7Smmcc if (keynote_env_lookup($1, &keynote_init_list, 1) != NULL)
249983e9580Sangelos {
250983e9580Sangelos free($1);
251983e9580Sangelos free($3);
252983e9580Sangelos keynote_errno = ERROR_SYNTAX;
253983e9580Sangelos return -1;
254983e9580Sangelos }
255983e9580Sangelos
256983e9580Sangelos i = keynote_env_add($1, $3, &keynote_init_list, 1, 0);
257983e9580Sangelos free($1);
258983e9580Sangelos free($3);
259983e9580Sangelos
260983e9580Sangelos if (i != RESULT_TRUE)
261983e9580Sangelos return -1;
262983e9580Sangelos } localconstants
263983e9580Sangelos
264983e9580Sangelos program: prog {
265983e9580Sangelos keynote_returnvalue = $1;
266983e9580Sangelos return 0;
267983e9580Sangelos }
268983e9580Sangelos
269983e9580Sangelos prog: /* Nada */ { $$ = 0; }
270983e9580Sangelos | notemptyprog {
271983e9580Sangelos /*
272983e9580Sangelos * Cleanup envlist of additions such as
273983e9580Sangelos * regexp results
274983e9580Sangelos */
275983e9580Sangelos keynote_env_cleanup(&keynote_temp_list, 1);
276983e9580Sangelos } SEMICOLON prog
277983e9580Sangelos {
278983e9580Sangelos if ($1 > $4)
279983e9580Sangelos $$ = $1;
280983e9580Sangelos else
281983e9580Sangelos $$ = $4;
282983e9580Sangelos }
283983e9580Sangelos
284983e9580Sangelos notemptyprog: expr HINT afterhint
285983e9580Sangelos {
286983e9580Sangelos if (checkexception($1))
287983e9580Sangelos $$ = $3;
288983e9580Sangelos else
289983e9580Sangelos $$ = 0;
290983e9580Sangelos }
291983e9580Sangelos | expr
292983e9580Sangelos {
293983e9580Sangelos if (checkexception($1))
294983e9580Sangelos $$ = keynote_current_session->ks_values_num - 1;
295983e9580Sangelos else
296983e9580Sangelos $$ = 0;
297983e9580Sangelos }
298983e9580Sangelos
299983e9580Sangelos afterhint: str { if (keynote_exceptionflag || keynote_donteval)
300983e9580Sangelos $$ = 0;
301983e9580Sangelos else
302983e9580Sangelos {
303983e9580Sangelos keynote_lex_remove($1);
304983e9580Sangelos
305983e9580Sangelos $$ = keynote_retindex($1);
306983e9580Sangelos if ($$ == -1) /* Invalid return value */
307983e9580Sangelos $$ = 0;
308983e9580Sangelos
309983e9580Sangelos free($1);
310983e9580Sangelos }
311983e9580Sangelos }
312983e9580Sangelos | OPENBLOCK prog CLOSEBLOCK { $$ = $2; }
313983e9580Sangelos
314983e9580Sangelos
315983e9580Sangelos expr: OPENPAREN expr CLOSEPAREN { $$ = $2; }
316983e9580Sangelos | expr AND { if ($1 == 0)
317983e9580Sangelos keynote_donteval = 1;
318983e9580Sangelos } expr { $$ = ($1 && $4);
319983e9580Sangelos keynote_donteval = 0;
320983e9580Sangelos }
321983e9580Sangelos | expr OR { if ($1)
322983e9580Sangelos keynote_donteval = 1;
323983e9580Sangelos } expr { $$ = ($1 || $4);
324983e9580Sangelos keynote_donteval = 0;
325983e9580Sangelos }
326983e9580Sangelos | NOT expr { $$ = !($2); }
327983e9580Sangelos | numexp { $$ = $1; }
328983e9580Sangelos | floatexp { $$ = $1; }
329983e9580Sangelos | stringexp { $$ = $1; }
330983e9580Sangelos | TRUE { $$ = 1; }
331983e9580Sangelos | FALSE { $$ = 0; }
332983e9580Sangelos
333983e9580Sangelos numexp: numex LT numex { $$ = $1 < $3; }
334983e9580Sangelos | numex GT numex { $$ = $1 > $3; }
335983e9580Sangelos | numex EQ numex { $$ = $1 == $3; }
336983e9580Sangelos | numex LE numex { $$ = $1 <= $3; }
337983e9580Sangelos | numex GE numex { $$ = $1 >= $3; }
338983e9580Sangelos | numex NE numex { $$ = $1 != $3; }
339983e9580Sangelos
340983e9580Sangelos floatexp: floatex LT floatex { $$ = $1 < $3; }
341983e9580Sangelos | floatex GT floatex { $$ = $1 > $3; }
342983e9580Sangelos | floatex LE floatex { $$ = $1 <= $3; }
343983e9580Sangelos | floatex GE floatex { $$ = $1 >= $3; }
344983e9580Sangelos
345983e9580Sangelos numex: numex PLUS numex { $$ = $1 + $3; }
346983e9580Sangelos | numex MINUS numex { $$ = $1 - $3; }
347983e9580Sangelos | numex MULT numex { $$ = $1 * $3; }
348983e9580Sangelos | numex DIV numex { if ($3 == 0)
349983e9580Sangelos {
350983e9580Sangelos if (!keynote_donteval)
351983e9580Sangelos keynote_exceptionflag = 1;
352983e9580Sangelos }
353983e9580Sangelos else
354983e9580Sangelos $$ = ($1 / $3);
355983e9580Sangelos }
356983e9580Sangelos | numex MOD numex { if ($3 == 0)
357983e9580Sangelos {
358983e9580Sangelos if (!keynote_donteval)
359983e9580Sangelos keynote_exceptionflag = 1;
360983e9580Sangelos }
361983e9580Sangelos else
362983e9580Sangelos $$ = $1 % $3;
363983e9580Sangelos }
364983e9580Sangelos | numex EXP numex { $$ = intpow($1, $3); }
365983e9580Sangelos | MINUS numex %prec UNARYMINUS { $$ = -($2); }
366983e9580Sangelos | OPENPAREN numex CLOSEPAREN { $$ = $2; }
367983e9580Sangelos | NUM { $$ = $1; }
368983e9580Sangelos | OPENNUM strnotconcat { if (keynote_exceptionflag ||
369983e9580Sangelos keynote_donteval)
370983e9580Sangelos $$ = 0;
371983e9580Sangelos else
372983e9580Sangelos {
373983e9580Sangelos keynote_lex_remove($2);
374983e9580Sangelos
375983e9580Sangelos if (!isfloatstring($2))
376983e9580Sangelos $$ = 0;
377983e9580Sangelos else
378983e9580Sangelos $$ = (int) floor(atof($2));
379983e9580Sangelos free($2);
380983e9580Sangelos }
381983e9580Sangelos }
382983e9580Sangelos
383983e9580Sangelos floatex: floatex PLUS floatex { $$ = ($1 + $3); }
384983e9580Sangelos | floatex MINUS floatex { $$ = ($1 - $3); }
385983e9580Sangelos | floatex MULT floatex { $$ = ($1 * $3); }
386983e9580Sangelos | floatex DIV floatex { if ($3 == 0)
387983e9580Sangelos {
388983e9580Sangelos if (!keynote_donteval)
389983e9580Sangelos keynote_exceptionflag = 1;
390983e9580Sangelos }
391983e9580Sangelos else
392983e9580Sangelos $$ = ($1 / $3);
393983e9580Sangelos }
394983e9580Sangelos | floatex EXP floatex { if (!keynote_exceptionflag &&
395983e9580Sangelos !keynote_donteval)
396983e9580Sangelos $$ = pow($1, $3);
397983e9580Sangelos }
398983e9580Sangelos | MINUS floatex %prec UNARYMINUS { $$ = -($2); }
399983e9580Sangelos | OPENPAREN floatex CLOSEPAREN { $$ = $2; }
400983e9580Sangelos | FLOAT { $$ = $1; }
401983e9580Sangelos | OPENFLT strnotconcat {
402983e9580Sangelos if (keynote_exceptionflag ||
403983e9580Sangelos keynote_donteval)
404983e9580Sangelos $$ = 0.0;
405983e9580Sangelos else
406983e9580Sangelos {
407983e9580Sangelos keynote_lex_remove($2);
408983e9580Sangelos
409983e9580Sangelos if (!isfloatstring($2))
410983e9580Sangelos $$ = 0.0;
411983e9580Sangelos else
412983e9580Sangelos $$ = atof($2);
413983e9580Sangelos free($2);
414983e9580Sangelos }
415983e9580Sangelos }
416983e9580Sangelos
417983e9580Sangelos stringexp: str EQ str {
418983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
419983e9580Sangelos $$ = 0;
420983e9580Sangelos else
421983e9580Sangelos {
422983e9580Sangelos $$ = strcmp($1, $3) == 0 ? 1 : 0;
423983e9580Sangelos keynote_lex_remove($1);
424983e9580Sangelos keynote_lex_remove($3);
425983e9580Sangelos free($1);
426983e9580Sangelos free($3);
427983e9580Sangelos }
428983e9580Sangelos }
429983e9580Sangelos | str NE str {
430983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
431983e9580Sangelos $$ = 0;
432983e9580Sangelos else
433983e9580Sangelos {
434983e9580Sangelos $$ = strcmp($1, $3) != 0 ? 1 : 0;
435983e9580Sangelos keynote_lex_remove($1);
436983e9580Sangelos keynote_lex_remove($3);
437983e9580Sangelos free($1);
438983e9580Sangelos free($3);
439983e9580Sangelos }
440983e9580Sangelos }
441983e9580Sangelos | str LT str {
442983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
443983e9580Sangelos $$ = 0;
444983e9580Sangelos else
445983e9580Sangelos {
446983e9580Sangelos $$ = strcmp($1, $3) < 0 ? 1 : 0;
447983e9580Sangelos keynote_lex_remove($1);
448983e9580Sangelos keynote_lex_remove($3);
449983e9580Sangelos free($1);
450983e9580Sangelos free($3);
451983e9580Sangelos }
452983e9580Sangelos }
453983e9580Sangelos | str GT str {
454983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
455983e9580Sangelos $$ = 0;
456983e9580Sangelos else
457983e9580Sangelos {
458983e9580Sangelos $$ = strcmp($1, $3) > 0 ? 1 : 0;
459983e9580Sangelos keynote_lex_remove($1);
460983e9580Sangelos keynote_lex_remove($3);
461983e9580Sangelos free($1);
462983e9580Sangelos free($3);
463983e9580Sangelos }
464983e9580Sangelos }
465983e9580Sangelos | str LE str {
466983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
467983e9580Sangelos $$ = 0;
468983e9580Sangelos else
469983e9580Sangelos {
470983e9580Sangelos $$ = strcmp($1, $3) <= 0 ? 1 : 0;
471983e9580Sangelos keynote_lex_remove($1);
472983e9580Sangelos keynote_lex_remove($3);
473983e9580Sangelos free($1);
474983e9580Sangelos free($3);
475983e9580Sangelos }
476983e9580Sangelos }
477983e9580Sangelos | str GE str {
478983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
479983e9580Sangelos $$ = 0;
480983e9580Sangelos else
481983e9580Sangelos {
482983e9580Sangelos $$ = strcmp($1, $3) >= 0 ? 1 : 0;
483983e9580Sangelos keynote_lex_remove($1);
484983e9580Sangelos keynote_lex_remove($3);
485983e9580Sangelos free($1);
486983e9580Sangelos free($3);
487983e9580Sangelos }
488983e9580Sangelos }
489983e9580Sangelos | str REGEXP str
490983e9580Sangelos {
491983e9580Sangelos regmatch_t pmatch[32];
492f91597c4Sderaadt char grp[10], *gr;
493983e9580Sangelos regex_t preg;
494983e9580Sangelos int i;
495983e9580Sangelos
496983e9580Sangelos if (keynote_exceptionflag || keynote_donteval)
497983e9580Sangelos $$ = 0;
498983e9580Sangelos else
499983e9580Sangelos {
500983e9580Sangelos keynote_lex_remove($1);
501983e9580Sangelos keynote_lex_remove($3);
502983e9580Sangelos
503983e9580Sangelos memset(pmatch, 0, sizeof(pmatch));
504983e9580Sangelos memset(grp, 0, sizeof(grp));
505983e9580Sangelos
506983e9580Sangelos if (regcomp(&preg, $3, REG_EXTENDED))
507983e9580Sangelos {
508983e9580Sangelos free($1);
509983e9580Sangelos free($3);
510983e9580Sangelos keynote_exceptionflag = 1;
511983e9580Sangelos }
512983e9580Sangelos else
513983e9580Sangelos {
514983e9580Sangelos /* Clean-up residuals from previous regexps */
515983e9580Sangelos keynote_env_cleanup(&keynote_temp_list, 1);
516983e9580Sangelos
517983e9580Sangelos free($3);
518983e9580Sangelos i = regexec(&preg, $1, 32, pmatch, 0);
519983e9580Sangelos $$ = (i == 0 ? 1 : 0);
520983e9580Sangelos if (i == 0)
521983e9580Sangelos {
522f91597c4Sderaadt snprintf(grp, sizeof grp, "%lu",
523f91597c4Sderaadt (unsigned long)preg.re_nsub);
524983e9580Sangelos if (keynote_env_add("_0", grp, &keynote_temp_list,
525983e9580Sangelos 1, 0) != RESULT_TRUE)
526983e9580Sangelos {
527983e9580Sangelos free($1);
528983e9580Sangelos regfree(&preg);
529983e9580Sangelos return -1;
530983e9580Sangelos }
531983e9580Sangelos
532983e9580Sangelos for (i = 1; i < 32 && pmatch[i].rm_so != -1; i++)
533983e9580Sangelos {
534983e9580Sangelos gr = calloc(pmatch[i].rm_eo - pmatch[i].rm_so +
535983e9580Sangelos 1, sizeof(char));
536313d0fe7Smmcc if (gr == NULL)
537983e9580Sangelos {
538983e9580Sangelos free($1);
539983e9580Sangelos regfree(&preg);
540983e9580Sangelos keynote_errno = ERROR_MEMORY;
541983e9580Sangelos return -1;
542983e9580Sangelos }
543983e9580Sangelos
544983e9580Sangelos strncpy(gr, $1 + pmatch[i].rm_so,
545983e9580Sangelos pmatch[i].rm_eo - pmatch[i].rm_so);
546983e9580Sangelos gr[pmatch[i].rm_eo - pmatch[i].rm_so] = '\0';
547f91597c4Sderaadt snprintf(grp, sizeof grp, "_%d", i);
548983e9580Sangelos if (keynote_env_add(grp, gr, &keynote_temp_list,
549983e9580Sangelos 1, 0) == -1)
550983e9580Sangelos {
551983e9580Sangelos free($1);
552983e9580Sangelos regfree(&preg);
553983e9580Sangelos free(gr);
554983e9580Sangelos return -1;
555983e9580Sangelos }
556983e9580Sangelos else
557983e9580Sangelos free(gr);
558983e9580Sangelos }
559983e9580Sangelos }
560983e9580Sangelos
561983e9580Sangelos regfree(&preg);
562983e9580Sangelos free($1);
563983e9580Sangelos }
564983e9580Sangelos }
565983e9580Sangelos }
566983e9580Sangelos
567983e9580Sangelos str: str DOTT str { if (keynote_exceptionflag || keynote_donteval)
568313d0fe7Smmcc $$ = NULL;
569983e9580Sangelos else
570983e9580Sangelos {
571f91597c4Sderaadt int len = strlen($1) + strlen($3) + 1;
572f91597c4Sderaadt $$ = calloc(len, sizeof(char));
573983e9580Sangelos keynote_lex_remove($1);
574983e9580Sangelos keynote_lex_remove($3);
575313d0fe7Smmcc if ($$ == NULL)
576983e9580Sangelos {
577983e9580Sangelos free($1);
578983e9580Sangelos free($3);
579983e9580Sangelos keynote_errno = ERROR_MEMORY;
580983e9580Sangelos return -1;
581983e9580Sangelos }
582f91597c4Sderaadt snprintf($$, len, "%s%s", $1, $3);
583983e9580Sangelos free($1);
584983e9580Sangelos free($3);
585983e9580Sangelos if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
586983e9580Sangelos return -1;
587983e9580Sangelos }
588983e9580Sangelos }
589983e9580Sangelos | strnotconcat { $$ = $1; }
590983e9580Sangelos
591983e9580Sangelos strnotconcat: STRING { $$ = $1; }
592983e9580Sangelos | OPENPAREN str CLOSEPAREN { $$ = $2; }
593983e9580Sangelos | VARIABLE { if (keynote_exceptionflag || keynote_donteval)
594313d0fe7Smmcc $$ = NULL;
595983e9580Sangelos else
596983e9580Sangelos {
597983e9580Sangelos $$ = my_lookup($1);
598983e9580Sangelos keynote_lex_remove($1);
599983e9580Sangelos free($1);
600313d0fe7Smmcc if ($$ == NULL)
601983e9580Sangelos {
602983e9580Sangelos if (keynote_errno)
603983e9580Sangelos return -1;
604983e9580Sangelos $$ = strdup("");
605983e9580Sangelos }
606983e9580Sangelos else
607983e9580Sangelos $$ = strdup($$);
608983e9580Sangelos
609313d0fe7Smmcc if ($$ == NULL)
610983e9580Sangelos {
611983e9580Sangelos keynote_errno = ERROR_MEMORY;
612983e9580Sangelos return -1;
613983e9580Sangelos }
614983e9580Sangelos
615983e9580Sangelos if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
616983e9580Sangelos return -1;
617983e9580Sangelos }
618983e9580Sangelos }
619983e9580Sangelos | DEREF str { if (keynote_exceptionflag || keynote_donteval)
620313d0fe7Smmcc $$ = NULL;
621983e9580Sangelos else
622983e9580Sangelos {
623983e9580Sangelos $$ = my_lookup($2);
624983e9580Sangelos keynote_lex_remove($2);
625983e9580Sangelos free($2);
626313d0fe7Smmcc if ($$ == NULL)
627983e9580Sangelos {
628983e9580Sangelos if (keynote_errno)
629983e9580Sangelos return -1;
630983e9580Sangelos $$ = strdup("");
631983e9580Sangelos }
632983e9580Sangelos else
633983e9580Sangelos $$ = strdup($$);
634983e9580Sangelos
635313d0fe7Smmcc if ($$ == NULL)
636983e9580Sangelos {
637983e9580Sangelos keynote_errno = ERROR_MEMORY;
638983e9580Sangelos return -1;
639983e9580Sangelos }
640983e9580Sangelos
641983e9580Sangelos if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
642983e9580Sangelos return -1;
643983e9580Sangelos }
644983e9580Sangelos }
645983e9580Sangelos %%
646983e9580Sangelos
647983e9580Sangelos /*
648983e9580Sangelos * Find all assertions signed by s and give us the one with the highest
649983e9580Sangelos * return value.
650983e9580Sangelos */
651983e9580Sangelos static int
652983e9580Sangelos resolve_assertion(char *s)
653983e9580Sangelos {
654983e9580Sangelos int i, alg = KEYNOTE_ALGORITHM_NONE, p = 0;
655983e9580Sangelos void *key = (void *) s;
656983e9580Sangelos struct assertion *as;
657983e9580Sangelos struct keylist *kl;
658983e9580Sangelos
659983e9580Sangelos kl = keynote_keylist_find(keynote_current_assertion->as_keylist, s);
660313d0fe7Smmcc if (kl != NULL)
661983e9580Sangelos {
662983e9580Sangelos alg = kl->key_alg;
663983e9580Sangelos key = kl->key_key;
664983e9580Sangelos }
665983e9580Sangelos
666983e9580Sangelos for (i = 0;; i++)
667983e9580Sangelos {
668983e9580Sangelos as = keynote_find_assertion(key, i, alg);
669313d0fe7Smmcc if (as == NULL) /* Gone through all of them */
670983e9580Sangelos return p;
671983e9580Sangelos
672983e9580Sangelos if (as->as_kresult == KRESULT_DONE)
673983e9580Sangelos if (p < as->as_result)
674983e9580Sangelos p = as->as_result;
675983e9580Sangelos
676983e9580Sangelos /* Short circuit if we find an assertion with maximum return value */
677983e9580Sangelos if (p == (keynote_current_session->ks_values_num - 1))
678983e9580Sangelos return p;
679983e9580Sangelos }
680983e9580Sangelos
681983e9580Sangelos return 0;
682983e9580Sangelos }
683983e9580Sangelos
684983e9580Sangelos /*
685983e9580Sangelos * Environment variable lookup.
686983e9580Sangelos */
687983e9580Sangelos static char *
my_lookup(char * s)688983e9580Sangelos my_lookup(char *s)
689983e9580Sangelos {
690983e9580Sangelos struct keynote_session *ks = keynote_current_session;
691983e9580Sangelos char *ret;
692983e9580Sangelos
693983e9580Sangelos if (!strcmp(s, "_MIN_TRUST"))
694983e9580Sangelos {
695983e9580Sangelos keynote_used_variable = 1;
696983e9580Sangelos return ks->ks_values[0];
697983e9580Sangelos }
698983e9580Sangelos else
699983e9580Sangelos {
700983e9580Sangelos if (!strcmp(s, "_MAX_TRUST"))
701983e9580Sangelos {
702983e9580Sangelos keynote_used_variable = 1;
703983e9580Sangelos return ks->ks_values[ks->ks_values_num - 1];
704983e9580Sangelos }
705983e9580Sangelos else
706983e9580Sangelos {
707983e9580Sangelos if (!strcmp(s, "_VALUES"))
708983e9580Sangelos {
709983e9580Sangelos keynote_used_variable = 1;
710983e9580Sangelos return keynote_env_lookup("_VALUES", ks->ks_env_table,
711983e9580Sangelos HASHTABLESIZE);
712983e9580Sangelos }
713983e9580Sangelos else
714983e9580Sangelos {
715983e9580Sangelos if (!strcmp(s, "_ACTION_AUTHORIZERS"))
716983e9580Sangelos {
717983e9580Sangelos keynote_used_variable = 1;
718983e9580Sangelos return keynote_env_lookup("_ACTION_AUTHORIZERS",
719983e9580Sangelos ks->ks_env_table, HASHTABLESIZE);
720983e9580Sangelos }
721983e9580Sangelos }
722983e9580Sangelos }
723983e9580Sangelos }
724983e9580Sangelos
725983e9580Sangelos /* Temporary list (regexp results) */
726eb225e73Sangelos if (keynote_temp_list != NULL)
727eb225e73Sangelos {
728983e9580Sangelos ret = keynote_env_lookup(s, &keynote_temp_list, 1);
729313d0fe7Smmcc if (ret != NULL)
730983e9580Sangelos return ret;
731983e9580Sangelos else
732983e9580Sangelos if (keynote_errno != 0)
733313d0fe7Smmcc return NULL;
734eb225e73Sangelos }
735983e9580Sangelos
736983e9580Sangelos /* Local-Constants */
737eb225e73Sangelos if (keynote_init_list != NULL)
738eb225e73Sangelos {
739983e9580Sangelos ret = keynote_env_lookup(s, &keynote_init_list, 1);
740313d0fe7Smmcc if (ret != NULL)
741983e9580Sangelos return ret;
742983e9580Sangelos else
743983e9580Sangelos if (keynote_errno != 0)
744313d0fe7Smmcc return NULL;
745eb225e73Sangelos }
746983e9580Sangelos
7479b935162Smillert if (ks != NULL)
748eb225e73Sangelos {
749983e9580Sangelos /* Action environment */
750983e9580Sangelos ret = keynote_env_lookup(s, ks->ks_env_table, HASHTABLESIZE);
751313d0fe7Smmcc if (ret != NULL)
752eb225e73Sangelos {
753eb225e73Sangelos keynote_used_variable = 1;
754983e9580Sangelos return ret;
755eb225e73Sangelos }
756983e9580Sangelos else
757983e9580Sangelos if (keynote_errno != 0)
758313d0fe7Smmcc return NULL;
759eb225e73Sangelos }
760983e9580Sangelos
761983e9580Sangelos /* Regex table */
762eb225e73Sangelos if ((ks != NULL) && (ks->ks_env_regex != NULL))
763eb225e73Sangelos {
764eb225e73Sangelos ret = keynote_env_lookup(s, &(ks->ks_env_regex), 1);
765313d0fe7Smmcc if (ret != NULL)
766eb225e73Sangelos {
767eb225e73Sangelos keynote_used_variable = 1;
768eb225e73Sangelos return ret;
769eb225e73Sangelos }
770eb225e73Sangelos
771313d0fe7Smmcc return NULL;
772eb225e73Sangelos }
773eb225e73Sangelos
774313d0fe7Smmcc return NULL;
775983e9580Sangelos }
776983e9580Sangelos
777983e9580Sangelos /*
778983e9580Sangelos * If we had an exception, the boolean expression should return false.
779983e9580Sangelos * Otherwise, return the result of the expression (the argument).
780983e9580Sangelos */
781983e9580Sangelos static int
checkexception(int i)782983e9580Sangelos checkexception(int i)
783983e9580Sangelos {
784983e9580Sangelos if (keynote_exceptionflag)
785983e9580Sangelos {
786983e9580Sangelos keynote_exceptionflag = 0;
787983e9580Sangelos return 0;
788983e9580Sangelos }
789983e9580Sangelos else
790983e9580Sangelos return i;
791983e9580Sangelos }
792983e9580Sangelos
793983e9580Sangelos
794983e9580Sangelos /*
795*2c53affbSjmc * Integer exponentiation -- copied from Schneier's AC2, page 244.
796983e9580Sangelos */
797983e9580Sangelos static int
intpow(int x,int y)798983e9580Sangelos intpow(int x, int y)
799983e9580Sangelos {
800983e9580Sangelos int s = 1;
801983e9580Sangelos
802983e9580Sangelos /*
803983e9580Sangelos * x^y with y < 0 is equivalent to 1/(x^y), which for
804983e9580Sangelos * integer arithmetic is 0.
805983e9580Sangelos */
806983e9580Sangelos if (y < 0)
807983e9580Sangelos return 0;
808983e9580Sangelos
809983e9580Sangelos while (y)
810983e9580Sangelos {
811983e9580Sangelos if (y & 1)
812983e9580Sangelos s *= x;
813983e9580Sangelos
814983e9580Sangelos y >>= 1;
815983e9580Sangelos x *= x;
816983e9580Sangelos }
817983e9580Sangelos
818983e9580Sangelos return s;
819983e9580Sangelos }
820983e9580Sangelos
821983e9580Sangelos /*
822983e9580Sangelos * Check whether the string is a floating point number.
823983e9580Sangelos */
824983e9580Sangelos static int
isfloatstring(char * s)825983e9580Sangelos isfloatstring(char *s)
826983e9580Sangelos {
827983e9580Sangelos int i, point = 0;
828983e9580Sangelos
829983e9580Sangelos for (i = strlen(s) - 1; i >= 0; i--)
83080c62621Sderaadt if (!isdigit((unsigned char)s[i]))
831983e9580Sangelos {
832983e9580Sangelos if (s[i] == '.')
833983e9580Sangelos {
834983e9580Sangelos if (point == 1)
835983e9580Sangelos return 0;
836983e9580Sangelos else
837983e9580Sangelos point = 1;
838983e9580Sangelos }
839983e9580Sangelos else
840983e9580Sangelos return 0;
841983e9580Sangelos }
842983e9580Sangelos
843983e9580Sangelos return 1;
844983e9580Sangelos }
845983e9580Sangelos
846983e9580Sangelos /*
847983e9580Sangelos * Initialize array for threshold search.
848983e9580Sangelos */
849983e9580Sangelos static int
keynote_init_kth(void)850983e9580Sangelos keynote_init_kth(void)
851983e9580Sangelos {
852983e9580Sangelos int i = keynote_current_session->ks_values_num;
853983e9580Sangelos
854983e9580Sangelos if (i == -1)
855983e9580Sangelos return -1;
856983e9580Sangelos
857313d0fe7Smmcc keynote_kth_array = calloc(i, sizeof(int));
858313d0fe7Smmcc if (keynote_kth_array == NULL)
859983e9580Sangelos {
860983e9580Sangelos keynote_errno = ERROR_MEMORY;
861983e9580Sangelos return -1;
862983e9580Sangelos }
863983e9580Sangelos
864983e9580Sangelos return RESULT_TRUE;
865983e9580Sangelos }
866983e9580Sangelos
867983e9580Sangelos /*
868983e9580Sangelos * Get the k-th best return value.
869983e9580Sangelos */
870983e9580Sangelos static int
get_kth(int k)871983e9580Sangelos get_kth(int k)
872983e9580Sangelos {
873983e9580Sangelos int i;
874983e9580Sangelos
875983e9580Sangelos for (i = keynote_current_session->ks_values_num - 1; i >= 0; i--)
876983e9580Sangelos {
877983e9580Sangelos k -= keynote_kth_array[i];
878983e9580Sangelos
879983e9580Sangelos if (k <= 0)
880983e9580Sangelos return i;
881983e9580Sangelos }
882983e9580Sangelos
883983e9580Sangelos return 0;
884983e9580Sangelos }
885983e9580Sangelos
886983e9580Sangelos /*
887983e9580Sangelos * Cleanup array.
888983e9580Sangelos */
889983e9580Sangelos void
keynote_cleanup_kth(void)890983e9580Sangelos keynote_cleanup_kth(void)
891983e9580Sangelos {
892313d0fe7Smmcc if (keynote_kth_array != NULL)
893983e9580Sangelos {
894983e9580Sangelos free(keynote_kth_array);
895313d0fe7Smmcc keynote_kth_array = NULL;
896983e9580Sangelos }
897983e9580Sangelos }
898983e9580Sangelos
899983e9580Sangelos void
knerror(char * s)900983e9580Sangelos knerror(char *s)
901983e9580Sangelos {}
902