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
