On 03/04/2016 12:16 AM, Tyler Hicks wrote:
> This patch separates the label parsing functionality from the program
> termination and memory allocation duties of parse_label(). This will
> ultimately help in creating simple helper functions that simply need to
> check if a label contains a namespace.
> 
> Signed-off-by: Tyler Hicks <[email protected]>

Acked-by: John Johansen <[email protected]>



> ---
>  parser/parser_misc.c | 94 
> +++++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 75 insertions(+), 19 deletions(-)
> 
> diff --git a/parser/parser_misc.c b/parser/parser_misc.c
> index 2348189..d0d8115 100644
> --- a/parser/parser_misc.c
> +++ b/parser/parser_misc.c
> @@ -569,24 +569,44 @@ int parse_X_mode(const char *X, int valid, const char 
> *str_mode, int *mode, int
>       return 1;
>  }
>  
> -void parse_label(char **ns, char **name, const char *label)
> +/**
> + * parse_label - break a label down to the namespace and profile name
> + * @ns: Will point to the first char in the namespace upon return or NULL
> + *      if no namespace is present
> + * @ns_len: Number of chars in the namespace string or 0 if no namespace
> + *          is present
> + * @name: Will point to the first char in the profile name upon return
> + * @name_len: Number of chars in the name string
> + * @label: The label to parse into namespace and profile name
> + *
> + * The returned pointers will point to locations within the original
> + * @label string. No new strings are allocated.
> + *
> + * Returns 0 upon success or non-zero with @ns, @ns_len, @name, and
> + * @name_len undefined upon error. Error codes are:
> + *
> + * 1) Namespace is not terminated despite @label starting with ':'
> + * 2) Namespace is empty meaning @label starts with "::"
> + * 3) Profile name is empty
> + */
> +static int _parse_label(char **ns, size_t *ns_len,
> +                     char **name, size_t *name_len,
> +                     const char *label)
>  {
>       const char *name_start = NULL;
> -     char *_ns = NULL;
> -     char *_name = NULL;
> +     const char *ns_start = NULL;
> +     const char *ns_end = NULL;
>  
>       if (label[0] != ':') {
>               /* There is no namespace specified in the label */
>               name_start = label;
>       } else {
>               /* A leading ':' indicates that a namespace is specified */
> -             const char *ns_start = label + 1;
> -             const char *ns_end = strstr(ns_start, ":");
> +             ns_start = label + 1;
> +             ns_end = strstr(ns_start, ":");
>  
>               if (!ns_end)
> -                     yyerror(_("Namespace not terminated: %s\n"), label);
> -             else if (ns_end - ns_start == 0)
> -                     yyerror(_("Empty namespace: %s\n"), label);
> +                     return 1;
>  
>               /**
>                * Handle either of the two namespace formats:
> @@ -596,23 +616,59 @@ void parse_label(char **ns, char **name, const char 
> *label)
>               name_start = ns_end + 1;
>               if (!strncmp(name_start, "//", 2))
>                       name_start += 2;
> -
> -             _ns = strndup(ns_start, ns_end - ns_start);
> -             if (!_ns)
> -                     yyerror(_("Memory allocation error."));
>       }
>  
> -     if (!strlen(name_start))
> +     /**
> +      * The casts below are to allow @label to be const, signifying
> +      * that this function doesn't modify it, while allowing callers to
> +      * decide if they want to pass in pointers to const or non-const
> +      * strings.
> +      */
> +     *ns = (char *)ns_start;
> +     *name = (char *)name_start;
> +     *ns_len = ns_end - ns_start;
> +     *name_len = strlen(name_start);
> +
> +     if (*ns && *ns_len == 0)
> +             return 2;
> +     else if (*name_len == 0)
> +             return 3;
> +
> +     return 0;
> +}
> +
> +void parse_label(char **_ns, char **_name, const char *label)
> +{
> +     char *ns = NULL;
> +     char *name = NULL;
> +     size_t ns_len = 0;
> +     size_t name_len = 0;
> +     int res;
> +
> +     res = _parse_label(&ns, &ns_len, &name, &name_len, label);
> +     if (res == 1) {
> +             yyerror(_("Namespace not terminated: %s\n"), label);
> +     } else if (res == 2) {
> +             yyerror(_("Empty namespace: %s\n"), label);
> +     } else if (res == 3) {
>               yyerror(_("Empty named transition profile name: %s\n"), label);
> +     } else if (res != 0) {
> +             yyerror(_("Unknown error while parsing label: %s\n"), label);
> +     }
>  
> -     _name = strdup(name_start);
> -     if (!_name) {
> -             free(_ns);
> -             yyerror(_("Memory allocation error."));
> +     if (ns) {
> +             *_ns = strndup(ns, ns_len);
> +             if (!*_ns)
> +                     yyerror(_("Memory allocation error."));
> +     } else {
> +             *_ns = NULL;
>       }
>  
> -     *ns = _ns;
> -     *name = _name;
> +     *_name = strndup(name, name_len);
> +     if (!*_name) {
> +             free(*_ns);
> +             yyerror(_("Memory allocation error."));
> +     }
>  }
>  
>  void parse_named_transition_target(struct named_transition *nt,
> 


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

Reply via email to