2
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
* NOVELL (All rights reserved)
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of version 2 of the GNU General Public
7
* License published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, contact Novell, Inc.
24
#include <linux/limits.h>
26
#define _(s) gettext(s)
32
static inline char *get_var_end(char *var)
39
if (!(*eptr == '_' || isalpha(*eptr)))
40
return NULL; /* invalid char */
43
return NULL; /* no terminating '}' */
46
static struct var_string *split_string(char *string, char *var_begin,
49
struct var_string *new = calloc(1, sizeof(struct var_string));
50
unsigned int offset = strlen("@{");
52
PERROR("Memory allocation error\n");
56
if (var_begin != string) {
57
new->prefix = strndup(string, var_begin - string);
60
new->var = strndup(var_begin + offset, var_end - (var_begin + offset));
62
if (strlen(var_end + 1) != 0) {
63
new->suffix = strdup(var_end + 1);
69
struct var_string *split_out_var(char *string)
71
struct var_string *new = NULL;
73
BOOL bEscape = 0; /* flag to indicate escape */
75
if (!string) /* shouldn't happen */
80
while (!new && *sptr) {
92
} else if (*(sptr + 1) == '{') {
93
char *eptr = get_var_end(sptr + 2);
95
break; /* no variable end found */
96
if (eptr == sptr + 2) {
97
/* XXX - better diagnostics here, please */
98
PERROR("Empty variable name found!\n");
101
new = split_string(string, sptr, eptr);
114
void free_var_string(struct var_string *var)
127
static int expand_entry_variables(struct cod_entry *entry)
129
struct set_value *valuelist;
132
struct var_string *split_var;
134
if (!entry) /* shouldn't happen */
137
while ((split_var = split_out_var(entry->name))) {
138
valuelist = get_set_var(split_var->var);
140
int boolean = get_boolean_var(split_var->var);
142
PERROR("Found reference to variable %s, but is never declared\n",
145
PERROR("Found reference to set variable %s, but declared boolean\n",
150
value = get_next_set_value(&valuelist);
152
PERROR("ASSERT: set variable (%s) should always have at least one value assigned to them\n",
157
if (asprintf(&(entry->name), "%s%s%s",
158
split_var->prefix ? split_var->prefix : "",
160
split_var->suffix ? split_var->suffix : "") == -1)
163
while ((value = get_next_set_value(&valuelist))) {
164
struct cod_entry *dupe = copy_cod_entry(entry);
166
PERROR("Memory allocaton error while handling set variable %s\n",
173
if (asprintf(&(entry->name), "%s%s%s",
174
split_var->prefix ? split_var->prefix : "", value,
175
split_var->suffix ? split_var->suffix : "") == -1)
179
free_var_string(split_var);
184
static int process_variables_in_entries(struct cod_entry *entry_list)
187
struct cod_entry *entry;
189
list_for_each(entry_list, entry) {
190
rc = expand_entry_variables(entry);
198
int process_variables(struct codomain *cod)
202
if (!process_variables_in_entries(cod->entries)) {
206
if (process_hat_variables(cod) != 0) {
213
#define MY_TEST(statement, error) \
214
if (!(statement)) { \
215
PERROR("FAIL: %s\n", error); \
219
/* Guh, fake routine */
220
void yyerror(char *msg, ...)
226
vsnprintf(buf, sizeof(buf), msg, arg);
229
PERROR(_("AppArmor parser error: %s\n"), buf);
233
/* Guh, fake symbol */
236
int test_get_var_end(void)
243
retchar = get_var_end(testchar);
244
MY_TEST(retchar - testchar == strlen("TRUE"), "get var end for TRUE}");
246
testchar = "some_var}some other text";
247
retchar = get_var_end(testchar);
248
MY_TEST(retchar - testchar == strlen("some_var"), "get var end for some_var}");
250
testchar = "some_var}some other} text";
251
retchar = get_var_end(testchar);
252
MY_TEST(retchar - testchar == strlen("some_var"), "get var end for some_var} 2");
255
retchar = get_var_end(testchar);
256
MY_TEST(retchar == NULL, "get var end for FALSE");
258
testchar = "pah,pah}pah ";
259
retchar = get_var_end(testchar);
260
MY_TEST(retchar == NULL, "get var end for pah,pah}");
265
int test_split_string(void)
268
char *tst_string, *var_start, *var_end;
269
struct var_string *ret_struct;
270
char *prefix = "abcdefg";
271
char *var = "boogie";
272
char *suffix = "suffixication";
274
(void) asprintf(&tst_string, "%s@{%s}%s", prefix, var, suffix);
275
var_start = tst_string + strlen(prefix);
276
var_end = var_start + strlen(var) + strlen("@\{");
277
ret_struct = split_string(tst_string, var_start, var_end);
278
MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split string 1 prefix");
279
MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 1 var");
280
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split string 1 suffix");
281
free_var_string(ret_struct);
283
asprintf(&tst_string, "@{%s}%s", var, suffix);
284
var_start = tst_string;
285
var_end = var_start + strlen(var) + strlen("@\{");
286
ret_struct = split_string(tst_string, var_start, var_end);
287
MY_TEST(ret_struct->prefix == NULL, "split string 2 prefix");
288
MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 2 var");
289
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split string 2 suffix");
290
free_var_string(ret_struct);
292
asprintf(&tst_string, "%s@{%s}", prefix, var);
293
var_start = tst_string + strlen(prefix);
294
var_end = var_start + strlen(var) + strlen("@\{");
295
ret_struct = split_string(tst_string, var_start, var_end);
296
MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split string 3 prefix");
297
MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 3 var");
298
MY_TEST(ret_struct->suffix == NULL, "split string 3 suffix");
299
free_var_string(ret_struct);
301
asprintf(&tst_string, "@{%s}", var);
302
var_start = tst_string;
303
var_end = var_start + strlen(var) + strlen("@\{");
304
ret_struct = split_string(tst_string, var_start, var_end);
305
MY_TEST(ret_struct->prefix == NULL, "split string 4 prefix");
306
MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 4 var");
307
MY_TEST(ret_struct->suffix == NULL, "split string 4 suffix");
308
free_var_string(ret_struct);
313
int test_split_out_var(void)
316
char *tst_string, *tmp;
317
struct var_string *ret_struct;
318
char *prefix = "abcdefg";
319
char *var = "boogie";
320
char *suffix = "suffixication";
323
asprintf(&tst_string, "%s@{%s}%s", prefix, var, suffix);
324
ret_struct = split_out_var(tst_string);
325
MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 1 prefix");
326
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 1 var");
327
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 1 suffix");
328
free_var_string(ret_struct);
331
asprintf(&tst_string, "@{%s}%s", var, suffix);
332
ret_struct = split_out_var(tst_string);
333
MY_TEST(ret_struct->prefix == NULL, "split out var 2 prefix");
334
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 2 var");
335
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 2 suffix");
336
free_var_string(ret_struct);
339
asprintf(&tst_string, "%s@{%s}", prefix, var);
340
ret_struct = split_out_var(tst_string);
341
MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 3 prefix");
342
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 3 var");
343
MY_TEST(ret_struct->suffix == NULL, "split out var 3 suffix");
344
free_var_string(ret_struct);
347
asprintf(&tst_string, "@{%s}", var);
348
ret_struct = split_out_var(tst_string);
349
MY_TEST(ret_struct->prefix == NULL, "split out var 4 prefix");
350
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 4 var");
351
MY_TEST(ret_struct->suffix == NULL, "split out var 4 suffix");
352
free_var_string(ret_struct);
354
/* quoted var, shouldn't split */
355
asprintf(&tst_string, "%s\\@{%s}%s", prefix, var, suffix);
356
ret_struct = split_out_var(tst_string);
357
MY_TEST(ret_struct == NULL, "split out var - quoted @");
358
free_var_string(ret_struct);
360
/* quoted \, split should succeed */
361
asprintf(&tst_string, "%s\\\\@{%s}%s", prefix, var, suffix);
362
ret_struct = split_out_var(tst_string);
363
MY_TEST(strcmp(ret_struct->prefix, strndup(tst_string, strlen(prefix) + 2)) == 0, "split out var 5 prefix");
364
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 5 var");
365
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 5 suffix");
366
free_var_string(ret_struct);
368
/* un terminated var, should fail */
369
asprintf(&tst_string, "%s@{%s%s", prefix, var, suffix);
370
ret_struct = split_out_var(tst_string);
371
MY_TEST(ret_struct == NULL, "split out var - un-terminated var");
372
free_var_string(ret_struct);
374
/* invalid char in var, should fail */
375
asprintf(&tst_string, "%s@{%s^%s}%s", prefix, var, var, suffix);
376
ret_struct = split_out_var(tst_string);
377
MY_TEST(ret_struct == NULL, "split out var - invalid char in var");
378
free_var_string(ret_struct);
380
/* two vars, should only strip out first */
381
asprintf(&tmp, "@{%s}%s}", suffix, suffix);
382
asprintf(&tst_string, "%s@{%s}%s", prefix, var, tmp);
383
ret_struct = split_out_var(tst_string);
384
MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 6 prefix");
385
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 6 var");
386
MY_TEST(strcmp(ret_struct->suffix, tmp) == 0, "split out var 6 suffix");
387
free_var_string(ret_struct);
389
/* quoted @ followed by var, split should succeed */
390
asprintf(&tst_string, "%s\\@@{%s}%s", prefix, var, suffix);
391
ret_struct = split_out_var(tst_string);
392
MY_TEST(strcmp(ret_struct->prefix, strndup(tst_string, strlen(prefix) + 2)) == 0, "split out var 7 prefix");
393
MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 7 var");
394
MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 7 suffix");
395
free_var_string(ret_struct);
404
retval = test_get_var_end();
408
retval = test_split_string();
412
retval = test_split_out_var();
418
#endif /* UNIT_TEST */