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 <[email protected]>

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-@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

Attachment: signature.asc
Description: Digital signature

-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to