[apparmor] [patch 05/26] cleanup/fix escape sequences in the backend and add support for \d
Seth Arnold
seth.arnold at canonical.com
Tue Apr 15 00:49:00 UTC 2014
On Mon, Apr 14, 2014 at 01:25:27PM -0700, John Johansen wrote:
> Alright here is a new revision of the patch. It folds in steve's test
> patch, but moves it to the lib.c file.
>
> In addition this patch unifies escape sequence handling (backend,
> processunqoted, processquoted), and adds a few lib routines and unit tests
> that are used by the escape sequence handling.
>
> It does not yet eliminate the double escape sequence handling that happens
> to items that pass through the lexer and then the backend. There is more
> work to be done before we can fix this properly.
>
> ---
>
> cleanup/fix escape sequences in the backend and add support for \d
>
> the octal escape sequence was broken, so that short escapes \0, \00 \xa,
> didn't work and actually resulted in some encoding bugs.
>
> Also we were missing support for the decimal # conversion \d123
>
> Signed-off-by: John Johansen <john.johansen at canonical.com>
Very nice cleanup, a few comments inline
>
> ---
> parser/Makefile | 4
> parser/lib.c | 289 +++++++++++++++++++++++++++++++++++++++++
> parser/lib.h | 13 +
> parser/libapparmor_re/Makefile | 2
> parser/libapparmor_re/parse.h | 1
> parser/libapparmor_re/parse.y | 92 +------------
> parser/parser_misc.c | 243 +++++++++++++++++++---------------
> 7 files changed, 457 insertions(+), 187 deletions(-)
>
> --- 2.9-test.orig/parser/Makefile
> +++ 2.9-test/parser/Makefile
> @@ -111,7 +111,7 @@
> LEX_C_FILES = parser_lex.c
> YACC_C_FILES = parser_yacc.c parser_yacc.h
>
> -TESTS = tst_regex tst_misc tst_symtab tst_variable
> +TESTS = tst_regex tst_misc tst_symtab tst_variable tst_lib
> TEST_CFLAGS = $(EXTRA_CFLAGS) -DUNIT_TEST -Wno-unused-result
> TEST_OBJECTS = $(filter-out \
> parser_lex.o \
> @@ -262,6 +262,8 @@
> cap_names.h: /usr/include/linux/capability.h
> echo "$(CAPABILITIES)" | LC_ALL=C sed -n -e "s/[ \\t]\\?CAP_\\([A-Z0-9_]\\+\\)/\{\"\\L\\1\", \\UCAP_\\1\},\\n/pg" > $@
>
> +tst_lib: lib.c parser.h $(filter-out lib.o, ${TEST_OBJECTS})
> + $(CXX) $(TEST_CFLAGS) -o $@ $< $(filter-out $(<:.c=.o), ${TEST_OBJECTS}) $(TEST_LDFLAGS)
> tst_%: parser_%.c parser.h $(filter-out parser_%.o, ${TEST_OBJECTS})
> $(CXX) $(TEST_CFLAGS) -o $@ $< $(filter-out $(<:.c=.o), ${TEST_OBJECTS}) $(TEST_LDFLAGS)
>
> --- 2.9-test.orig/parser/lib.c
> +++ 2.9-test/parser/lib.c
> @@ -29,6 +29,7 @@
> #include <sys/stat.h>
> #include <sys/types.h>
>
> +#include "lib.h"
> #include "parser.h"
>
> /**
> @@ -135,3 +136,291 @@
>
> return -1;
> }
> +
> +/**
> + * isodigit - test if a character is an octal digit
> + * @c: character to test
> + *
> + * Returns: true if an octal digit, else false
> + */
> +bool isodigit(char c)
> +{
> + return (c >= '0' && c <= '7') ? true : false;
> +}
> +
> +/* convert char character 0..9a..z into a number 0-35
> + *
> + * Returns: digit value of character or -1 if character is invalid
> + */
> +static int chrtoi(char c, int base)
> +{
> + int val = -1;
> +
> + if (base < 2 || base > 36)
> + return -1;
> +
> + if (isdigit(c))
> + val = c - '0';
> + else if (isalpha(c) && isascii(c))
> + val = tolower(c) - 'a' + 10;
> +
> + if (val >= base)
> + return -1;
> +
> + return val;
> +}
> +
> +/**
> + * strntol - convert a sequence of characters as a hex number
> + * @str: pointer to a string of character to convert
> + * @endptr: RETURNS: if not NULL, the first char after converted chars.
> + * @base: base of convertion
> + * @maxval: maximum value. don't consume next char if value will exceed @maxval
> + * @n: maximum number of characters to consume doing the conversion
> + *
> + * Returns: converted number. If there is no conversion 0 is returned and
> + * *@endptr = @str
> + *
> + * Not a complete replacement for strtol yet, Does not process base prefixes,
> + * nor +/- sign yet.
> + *
> + * - take the largest sequence of character that is in range of 0- at maxval
> + * - will consume the minimum of @maxlen or @base digits in @maxval
> + * - if there is not n valid characters for the base only the n-1 will be taken
> + * eg. for the sequence string 4z with base 16 only 4 will be taken as the
> + * hex number
> + */
> +long strntol(const char *str, const char **endptr, int base, long maxval,
> + size_t n)
> +{
> + long c, val = 0;
> +
> + if (base > 1 && base < 37) {
> + for (; n && (c = chrtoi(*str, base)) != -1; str++, n--) {
> + long tmp = (val * base) + c;
> + if (tmp > maxval)
> + break;
> + val = tmp;
> + }
> + }
> +
> + if (endptr)
> + *endptr = str;
> +
> + return val;
> +}
> +
> +/**
> + * strn_escseq -
> + * @pos: position of first character in esc sequence
> + * @n: maximum length of string to processes
> + *
> + * Returns: character for escape sequence or -1 if an error
> + *
> + * pos will point to first character after esc sequence
> + * OR
> + * pos will point to first character where an error was discovered
> + * errors can be unrecognized esc character, octal, decimal, or hex
> + * character encoding with no valid number. eg. \xT
> + */
> +int strn_escseq(const char **pos, size_t n)
> +{
> + const char *end;
> + long tmp;
> +
> + if (n < 1)
> + return -1;
> +
> + if (isodigit(**pos)) {
> + tmp = strntol(*pos, &end, 8, 255, min(3ul, n));
> + if (tmp == 0 && end == *pos) {
> + /* this should never happen because of isodigit test */
> + return -1;
> + }
> + *pos = end;
> + return tmp;
> + }
> +
> + switch(*(*pos)++) {
> + case '\0':
> + (*pos)--;
> + /* fall through */
> + case '\\':
> + return '\\';
I don't care much for falling through, especially when the thing
falled-through-to is shorter and easier than the /* fall through */
comment itself.
> + case '"':
> + return '"';
> + case 'd':
> + tmp = strntol(*pos, &end, 10, 255, min(3ul, n));
> + if (tmp == 0 && end == *pos) {
> + /* \d no valid encoding */
> + return -1;
> + }
> + *pos = end;
> + return tmp;
> + case 'x':
> + tmp = strntol(*pos, &end, 16, 255, min(2ul, n));
> + if (tmp == 0 && end == *pos) {
> + /* \x no valid encoding */
> + return -1;
> + }
> + *pos = end;
> + return tmp;
> + case 'a':
> + return '\a';
> + case 'e':
> + return 033 /* ESC */;
> + case 'f':
> + return '\f';
> + case 'n':
> + return '\n';
> + case 'r':
> + return '\r';
> + case 't':
> + return '\t';
> + }
> + /* unsupported escap sequence, backup to return that char */
> + pos--;
> + return -1;
> +}
> +
> +int str_escseq(const char **pos)
> +{
> + /* no len limit just use end of string */
> + return strn_escseq(pos, SIZE_MAX);
> +}
> +
> +#ifdef UNIT_TEST
> +
> +#include "lib.h"
> +#include "parser.h"
> +#include "unit_test.h"
> +
> +static int test_oct(const char *str)
> +{
> + const char *end;
> + long retval = strntol(str, &end, 8, 255, 3);
> + if (retval == 0 && str == end)
> + return -1;
> + return retval;
> +}
> +
> +static int test_dec(const char *str)
> +{
> + const char *end;
> + long retval = strntol(str, &end, 10, 255, 3);
> + if (retval == 0 && str == end)
> + return -1;
> + return retval;
> +}
> +
> +static int test_hex(const char *str)
> +{
> + const char *end;
> + long retval = strntol(str, &end, 16, 255, 2);
> + if (retval == 0 && str == end)
> + return -1;
> + return retval;
> +}
> +
> +int main(void)
> +{
> + int rc = 0;
> + int retval;
The indenting of 'int rc' is different than expected.
> +
> + struct test_struct {
> + const char *test; /* test string */
> + int expected; /* expected result */
> + const char *msg; /* failure message */
> + };
> +
> + struct test_struct oct_tests[] = {
> + { "0a", 0, "oct conversion of \\0a failed" },
> + { "00000003a", 0, "oct conversion of \\00000003a failed" },
> + { "62", 50, "oct conversion of \\62 failed" },
> + { "623", 50, "oct conversion of \\623 failed" },
> + { "123", 83, "oct conversion of \\123 failed" },
> + { "123;", 83, "oct conversion of \\123; failed" },
> + { "2234", 147, "oct conversion of \\2234 failed" },
> + { "xx", -1, "oct conversion of \\xx failed" },
> + { NULL, 0, NULL }
> + };
> +
> + struct test_struct dec_tests[] = {
> + { "0a", 0, "dec conversion of \\d0a failed" },
> + { "00000003a", 0, "dec conversion of \\d00000003a failed" },
> + { "62", 62, "dec conversion of \\d62 failed" },
> + { "623", 62, "dec conversion of \\d623 failed" },
> + { "132", 132, "dec conversion of \\d132 failed" },
> + { "132UL", 132, "dec conversion of \\d132UL failed" },
> + { "255", 255, "dec conversion of \\d255 failed" },
> + { "256", 25, "dec conversion of \\d256 failed" },
> + { "2234", 223, "dec conversion of \\d2234 failed" },
> + { "xx", -1, "dec conversion of \\dxx failed" },
> + { NULL, 0, NULL }
> + };
> +
> + struct test_struct hex_tests[] = {
> + { "0", 0x0, "hex conversion of 0x0 failed" },
> + { "0x1", 0x0, "hex conversion of 0x0x1 failed" },
> + { "1x", 0x1, "hex conversion of 0x1x failed" },
> + { "00", 0x0, "hex conversion of 0x00 failed" },
> + { "00x", 0x0, "hex conversion of 0x00x failed" },
> + { "01", 0x1, "hex conversion of 0x01 failed" },
> + { "01x", 0x1, "hex conversion of 0x01x failed" },
> + { "ab", 0xab, "hex conversion of 0xAb failed" },
> + { "AB", 0xab, "hex conversion of 0xAB failed" },
> + { "Ab", 0xab, "hex conversion of 0xAb failed" },
> + { "aB", 0xab, "hex conversion of 0xaB failed" },
> + { "4z", 0x4, "hex conversion of 0x4z failed" },
> + { "123", 0x12, "hex conversion of 0x123 failed" },
> + { "12M", 0x12, "hex conversion of 0x12M failed" },
> + { "ff", 0xff, "hex conversion of 0x255 failed" },
> + { "FF", 0xff, "hex conversion of 0x255 failed" },
> + { "XX", -1, "hex conversion of 0xXX failed" },
> + { NULL, 0, NULL }
> + };
> +
> + /* test chrtoi */
> + for (int base = -1; base < 38; base++) {
> + for (int c = 0; c < 256; c++) {
> + int expected;
> + int i = chrtoi(c, base);
> + if (base < 2 || base > 36 || !isascii(c) || !(isdigit(c) || isalpha(c)))
> + expected = -1;
> + else if (isdigit(c) && (c - '0') < base)
> + expected = toupper(c) - '0';
toupper(c) of a digit is a noop; might as well remove it.
> + else if (isalpha(c) && (toupper(c) - 'A') + 10 < base)
> + expected = (toupper(c) - 'A') + 10;
> + else
> + expected = -1;
> + if (i != expected)
> + printf(" chrtoi test: convert base %d '%c'(%d)\texpected %d\tresult: %d\n", base, c, c, expected, i);
> + MY_TEST(i == expected, "failed");
> + }
> + }
> +
> + /* test strntol */
> + for (struct test_struct *t = oct_tests; t->test; t++) {
> + retval = test_oct(t->test);
> + printf(" oct test: %s\texpected %d\tresult: %d\n", t->test, t->expected, retval);
> + MY_TEST(retval == t->expected, t->msg);
> + }
> +
> + for (struct test_struct *t = dec_tests; t->test; t++) {
> + retval = test_dec(t->test);
> + printf(" dec test: %s\texpected %d\tresult: %d\n", t->test, t->expected, retval);
> + MY_TEST(retval == t->expected, t->msg);
> + }
> +
> + for (struct test_struct *t = hex_tests; t->test; t++) {
> + retval = test_hex(t->test);
> + printf(" hex test: %s\texpected %d\tresult: %d\n", t->test, t->expected, retval);
> + MY_TEST(retval == t->expected, t->msg);
> + }
> +
> + /* test strn_escseq */
> + /* TODO: */
> + return rc;
> +}
> +
> +#endif /* UNIT_TEST */
> --- 2.9-test.orig/parser/lib.h
> +++ 2.9-test/parser/lib.h
> @@ -1,7 +1,20 @@
> #ifndef __AA_LIB_H_
> #define __AA_LIB_H_
>
> +#include <dirent.h>
> +
> +#define min(a,b) \
> + ({ __typeof__ (a) _a = (a); \
> + __typeof__ (b) _b = (b); \
> + _a < _b ? _a : _b; })
> +
> int dirat_for_each(DIR *dir, const char *name, void *data,
> int (* cb)(DIR *, const char *, struct stat *, void *));
>
> +bool isodigit(char c);
> +long strntol(const char *str, const char **endptr, int base, long maxval,
> + size_t n);
> +int strn_escseq(const char **pos, size_t n);
> +int str_escseq(const char **pos);
> +
> #endif /* __AA_LIB_H_ */
> --- 2.9-test.orig/parser/libapparmor_re/Makefile
> +++ 2.9-test/parser/libapparmor_re/Makefile
> @@ -12,6 +12,8 @@
>
> all : ${TARGET}
>
> +UNITTESTS = tst_parse
> +
> libapparmor_re.a: parse.o expr-tree.o hfa.o chfa.o aare_rules.o
> ar ${ARFLAGS} $@ $^
>
> --- 2.9-test.orig/parser/libapparmor_re/parse.h
> +++ 2.9-test/parser/libapparmor_re/parse.h
> @@ -24,4 +24,5 @@
>
> int regex_parse(Node **tree, const char *rule);
>
> +
> #endif /* __LIBAA_RE_PARSE_H */
The above newline doesn't do much, unless you really want the extra space.
> --- 2.9-test.orig/parser/libapparmor_re/parse.y
> +++ 2.9-test/parser/libapparmor_re/parse.y
> @@ -155,30 +155,13 @@
>
> %%
>
> -
> -int octdigit(char c)
> -{
> - if (c >= '0' && c <= '7')
> - return c - '0';
> - return -1;
> -}
> -
> -int hexdigit(char c)
> -{
> - if (c >= '0' && c <= '9')
> - return c - '0';
> - else if (c >= 'A' && c <= 'F')
> - return 10 + c - 'A';
> - else if (c >= 'a' && c <= 'f')
> - return 10 + c - 'a';
> - else
> - return -1;
> -}
> +#include "../lib.h"
>
> int regex_lex(YYSTYPE *val, const char **pos)
> {
> - int c;
> + int tmp;
>
> +start:
> val->c = **pos;
> switch(*(*pos)++) {
> case '\0':
> @@ -190,67 +173,14 @@
> return *(*pos - 1);
>
> case '\\':
> - val->c = **pos;
> - switch(*(*pos)++) {
> - case '\0':
> - (*pos)--;
> - /* fall through */
> - case '\\':
> - val->c = '\\';
> - break;
> -
> - case '0':
> - val->c = 0;
> - if ((c = octdigit(**pos)) >= 0) {
> - val->c = c;
> - (*pos)++;
> - }
> - if ((c = octdigit(**pos)) >= 0) {
> - val->c = (val->c << 3) + c;
> - (*pos)++;
> - }
> - if ((c = octdigit(**pos)) >= 0) {
> - val->c = (val->c << 3) + c;
> - (*pos)++;
> - }
> - break;
> -
> - case 'x':
> - val->c = 0;
> - if ((c = hexdigit(**pos)) >= 0) {
> - val->c = c;
> - (*pos)++;
> - }
> - if ((c = hexdigit(**pos)) >= 0) {
> - val->c = (val->c << 4) + c;
> - (*pos)++;
> - }
> - break;
> -
> - case 'a':
> - val->c = '\a';
> - break;
> -
> - case 'e':
> - val->c = 033 /* ESC */;
> - break;
> -
> - case 'f':
> - val->c = '\f';
> - break;
> -
> - case 'n':
> - val->c = '\n';
> - break;
> -
> - case 'r':
> - val->c = '\r';
> - break;
> -
> - case 't':
> - val->c = '\t';
> - break;
> - }
> + tmp = str_escseq(pos);
> + if (tmp == -1)
> + /* bad escape sequence, just skip it for now
> + * TODO: output error message
> + */
> + goto start;
> + val->c = tmp;
> + break;
> }
> return CHAR;
> }
> --- 2.9-test.orig/parser/parser_misc.c
> +++ 2.9-test/parser/parser_misc.c
> @@ -39,6 +39,7 @@
> #include <unistd.h>
> #include <sys/apparmor.h>
>
> +#include "lib.h"
> #include "parser.h"
> #include "profile.h"
> #include "parser_yacc.h"
> @@ -443,38 +444,70 @@
>
> char *processunquoted(const char *string, int len)
> {
> - char *tmp, *s;
> - int l;
> + char *buffer, *s;
>
> - tmp = (char *)malloc(len + 1);
> - if (!tmp)
> + s = buffer = (char *) malloc(len + 1);
> + if (!buffer)
> return NULL;
>
> - s = tmp;
> - for (l = 0; l < len; l++) {
> - if (string[l] == '\\' && l < len - 3) {
> - if (strchr("0123", string[l + 1]) &&
> - strchr("0123456789", string[l + 2]) &&
> - strchr("0123456789", string[l + 3])) {
> - /* three digit octal */
> - int res = (string[l + 1] - '0') * 64 +
> - (string[l + 2] - '0') * 8 +
> - (string[l + 3] - '0');
> - *s = res;
> - l += 3;
> + while (len > 0) {
> + const char *pos = string + 1;
> + long c;
> + if (*string == '\\' && len > 1 &&
> + (c = strn_escseq(&pos, len)) != -1) {
> + *s++ = c;
> + len -= pos - string;
> + string = pos;
> + } else {
> + /* either unescaped char OR
> + * unsupported escape sequence resulting in char being
> + * copied.
> + */
> + *s++ = *string++;
> + len--;
> + }
> +#if 0
> + if (*string == '\\' && len > 1) {
> + string++;
> + len--;
> + const char *pos = string;
> + long c;
> + if ((c = strn_escseq(&pos, len)) != -1) {
> + *s++ = c;
> + len -= pos - string;
> + string = pos;
> } else {
> - *s = string[l];
> + *s++ = '\\';
> }
> - s++;
> } else {
> - *s = string[l];
> - s++;
> + /* either unescaped char OR
> + * unsupported escape sequence resulting in char being
> + * copied.
> + */
> + *s++ = *string++;
> + len--;
> }
> +#endif
> }
> -
> *s = 0;
>
> - return tmp;
> + return buffer;
> +}
> +
> +/* rewrite a quoted string substituting escaped characters for the
> + * real thing. Strip the quotes around the string */
> +char *processquoted(const char *string, int len)
> +{
> + /* skip leading " and eat trailing " */
> + if (*string == '"') {
> + len -= 2;
> + if (len < 0) /* start and end point to same quote */
> + len = 0;
> + return processunquoted(string + 1, len);
> + }
> +
> + /* no quotes? treat as unquoted */
> + return processunquoted(string, len);
> }
>
> char *processid(const char *string, int len)
> @@ -487,72 +520,6 @@
> return processunquoted(string, len);
> }
>
> -/* rewrite a quoted string substituting escaped characters for the
> - * real thing. Strip the quotes around the string */
> -
> -char *processquoted(const char *string, int len)
> -{
> - char *tmp, *s;
> - int l;
> - /* the result string will be shorter or equal in length */
> - tmp = (char *)malloc(len + 1);
> - if (!tmp)
> - return NULL;
> -
> - s = tmp;
> - for (l = 1; l < len - 1; l++) {
> - if (string[l] == '\\' && l < len - 2) {
> - switch (string[l + 1]) {
> - case 't':
> - *s = '\t';
> - l++;
> - break;
> - case 'n':
> - *s = '\n';
> - l++;
> - break;
> - case 'r':
> - *s = '\r';
> - l++;
> - break;
> - case '"':
> - *s = '"';
> - l++;
> - break;
> - case '\\':
> - *s = '\\';
> - l++;
> - break;
> - case '0': case '1': case '2': case '3':
> - if ((l < len - 4) &&
> - strchr("0123456789", string[l + 2]) &&
> - strchr("0123456789", string[l + 3])) {
> - /* three digit octal */
> - int res = (string[l + 1] - '0') * 64 +
> - (string[l + 2] - '0') * 8 +
> - (string[l + 3] - '0');
> - *s = res;
> - l += 3;
> - break;
> - }
> - /* fall through */
> - default:
> - /* any unsupported escape sequence results in all
> - chars being copied. */
> - *s = string[l];
> - }
> - s++;
> - } else {
> - *s = string[l];
> - s++;
> - }
> - }
> -
> - *s = 0;
> -
> - return tmp;
> -}
> -
> /* strip off surrounding delimiters around variables */
> char *process_var(const char *var)
> {
> @@ -1270,27 +1237,82 @@
> int test_processunquoted(void)
> {
> int rc = 0;
> - const char *teststring, *processedstring;
> + const char *teststring;
> + const char *resultstring;
>
> teststring = "";
> MY_TEST(strcmp(teststring, processunquoted(teststring, strlen(teststring))) == 0,
> "processunquoted on empty string");
>
> + teststring = "\\1";
> + resultstring = "\001";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on one digit octal");
> +
> + teststring = "\\8";
> + resultstring = "\\8";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on invalid octal digit \\8");
> +
> + teststring = "\\18";
> + resultstring = "\0018";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on one digit octal followed by invalid octal digit");
> +
> + teststring = "\\1a";
> + resultstring = "\001a";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on one digit octal followed by hex digit a");
> +
> + teststring = "\\1z";
> + resultstring = "\001z";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on one digit octal follow by char z");
> +
> + teststring = "\\11";
> + resultstring = "\011";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on two digit octal");
> +
> + teststring = "\\118";
> + resultstring = "\0118";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on two digit octal followed by invalid octal digit");
> +
> + teststring = "\\11a";
> + resultstring = "\011a";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on two digit octal followed by hex digit a");
> +
> + teststring = "\\11z";
> + resultstring = "\011z";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on two digit octal followed by char z");
> +
> + teststring = "\\111";
> + resultstring = "\111";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on three digit octal");
> +
> + teststring = "\\378";
> + resultstring = "\0378";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on three digit octal two large, taken as 2 digit octal plus trailing char");
> +
> teststring = "123\\421123";
> - MY_TEST(strcmp(teststring, processunquoted(teststring, strlen(teststring))) == 0,
> - "processunquoted on invalid octal");
> + resultstring = "123\0421123";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on two character octal followed by valid octal digit \\421");
>
> -/* Oh wow, our octal processing is busticated - FIXME
> teststring = "123\\109123";
> - processedstring = "123\109123";
> - MY_TEST(strcmp(processedstring, processunquoted(teststring, strlen(teststring))) == 0,
> - "processunquoted on octal 10");
> + resultstring = "123\109123";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on octal 109");
>
> teststring = "123\\189123";
> - processedstring = "123\189123";
> - MY_TEST(strcmp(processedstring, processunquoted(teststring, strlen(teststring))) == 0,
> - "processunquoted on octal 10");
> -*/
> + resultstring = "123\189123";
> + MY_TEST(strcmp(resultstring, processunquoted(teststring, strlen(teststring))) == 0,
> + "processunquoted on octal 108");
The error message says "108" but teststring doesn't have "108".
>
> return rc;
> }
> @@ -1377,19 +1399,30 @@
> "processquoted on quoted octal \\176");
> free(out);
>
> - /* yes, our octal processing is lame; patches accepted */
> - teststring = "\"abc\\42defg\"";
> - processedstring = "abc\\42defg";
> + teststring = "\"abc\\429defg\"";
> + processedstring = "abc\0429defg";
> out = processquoted(teststring, strlen(teststring));
> MY_TEST(strcmp(processedstring, out) == 0,
> - "processquoted passthrough quoted invalid octal \\42");
> + "processquoted passthrough quoted invalid octal \\429");
> free(out);
>
> + teststring = "\"abcdefg\\4\"";
> + processedstring = "abcdefg\004";
> + out = processquoted(teststring, strlen(teststring));
> + MY_TEST(strcmp(processedstring, out) == 0,
> + "processquoted passthrough quoted one digit trailing octal \\4");
> +
> teststring = "\"abcdefg\\04\"";
> - processedstring = "abcdefg\\04";
> + processedstring = "abcdefg\004";
> + out = processquoted(teststring, strlen(teststring));
> + MY_TEST(strcmp(processedstring, out) == 0,
> + "processquoted passthrough quoted two digit trailing octal \\04");
> +
> + teststring = "\"abcdefg\\004\"";
> + processedstring = "abcdefg\004";
> out = processquoted(teststring, strlen(teststring));
> MY_TEST(strcmp(processedstring, out) == 0,
> - "processquoted passthrough quoted invalid trailing octal \\04");
> + "processquoted passthrough quoted three digit trailing octal \\004");
> free(out);
>
> return rc;
>
Thanks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20140414/87b72b08/attachment-0001.pgp>
More information about the AppArmor
mailing list