diff --git a/src/acl.c b/src/acl.c index b2b0f0c1c..6d11a0b35 100644 --- a/src/acl.c +++ b/src/acl.c @@ -121,7 +121,8 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr) /* Parse an ACL expression starting at [0], and return it. If is * not NULL, it will be filled with a pointer to an error message in case of * error. This pointer must be freeable or NULL. is an arg_list serving - * as a list head to report missing dependencies. + * as a list head to report missing dependencies. It may be NULL if such + * dependencies are not allowed. * * Right now, the only accepted syntax is : * [...] @@ -162,9 +163,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list * * keyword. */ - al->ctx = ARGC_ACL; // to report errors while resolving args late - al->kw = *args; - al->conv = NULL; + if (al) { + al->ctx = ARGC_ACL; // to report errors while resolving args late + al->kw = *args; + al->conv = NULL; + } aclkw = find_acl_kw(args[0]); if (aclkw) { @@ -280,8 +283,10 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list * conv_expr->conv = conv; acl_conv_found = 1; - al->kw = smp->fetch->kw; - al->conv = conv_expr->conv->kw; + if (al) { + al->kw = smp->fetch->kw; + al->conv = conv_expr->conv->kw; + } argcnt = make_arg_list(endw, -1, conv->arg_mask, &conv_expr->arg_p, err, &arg, &err_arg, al); if (argcnt < 0) { memprintf(err, "ACL keyword '%s' : invalid arg %d in converter '%s' : %s.", @@ -665,7 +670,7 @@ struct acl *prune_acl(struct acl *acl) { * an anonymous one and it won't be merged with any other one. If is not * NULL, it will be filled with an appropriate error. This pointer must be * freeable or NULL. is the arg_list serving as a head for unresolved - * dependencies. + * dependencies. It may be NULL if such dependencies are not allowed. * * args syntax: */ @@ -778,7 +783,8 @@ const struct { * If is not NULL, the ACL will be queued at its tail. If is * not NULL, it will be filled with an error message if an error occurs. This * pointer must be freeable or NULL. is an arg_list serving as a list head - * to report missing dependencies. + * to report missing dependencies. It may be NULL if such dependencies are not + * allowed. */ static struct acl *find_acl_default(const char *acl_name, struct list *known_acl, char **err, struct arg_list *al, @@ -858,7 +864,8 @@ struct acl_cond *prune_acl_cond(struct acl_cond *cond) * is not NULL, it will be filled with a pointer to an error message in * case of error, that the caller is responsible for freeing. The initial * location must either be freeable or NULL. The list serves as a list head - * for unresolved dependencies. + * for unresolved dependencies. It may be NULL if such dependencies are not + * allowed. */ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, enum acl_cond_pol pol, char **err, struct arg_list *al, diff --git a/src/arg.c b/src/arg.c index 140fbeff9..039602a49 100644 --- a/src/arg.c +++ b/src/arg.c @@ -97,14 +97,15 @@ struct arg_list *arg_list_add(struct arg_list *orig, struct arg *arg, int pos) * The returned array is always terminated by an arg of type ARGT_STOP (0), * unless the mask indicates that no argument is supported. Unresolved arguments * are appended to arg list , which also serves as a template to create new - * entries. The mask is composed of a number of mandatory arguments in its lower - * ARGM_BITS bits, and a concatenation of each argument type in each subsequent - * ARGT_BITS-bit sblock. If is not NULL, it must point to a freeable - * or NULL pointer. The caller is expected to restart the parsing from the new - * pointer set in , which is the first character considered as not - * being part of the arg list. The input string ends on the first between - * characters (when len is positive) or the first NUL character. Placing -1 in - * will make it virtually unbounded (~2GB long strings). + * entries. may be NULL if unresolved arguments are not allowed. The mask + * is composed of a number of mandatory arguments in its lower ARGM_BITS bits, + * and a concatenation of each argument type in each subsequent ARGT_BITS-bit + * sblock. If is not NULL, it must point to a freeable or NULL + * pointer. The caller is expected to restart the parsing from the new pointer + * set in , which is the first character considered as not being part + * of the arg list. The input string ends on the first between characters + * (when len is positive) or the first NUL character. Placing -1 in will + * make it virtually unbounded (~2GB long strings). */ int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp, char **err_msg, const char **end_ptr, int *err_arg, @@ -245,6 +246,8 @@ int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp, /* These argument types need to be stored as strings during * parsing then resolved later. */ + if (!al) + goto resolve_err; arg->unresolved = 1; new_al = arg_list_add(al, arg, pos); @@ -447,6 +450,11 @@ int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp, alloc_err: memprintf(err_msg, "out of memory"); goto err; + + resolve_err: + memprintf(err_msg, "unresolved argument of type '%s' at position %d not allowed", + arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1); + goto err; } /* Free all args of an args array, taking care of unresolved arguments as well. diff --git a/src/sample.c b/src/sample.c index ab37a9674..ed95545c8 100644 --- a/src/sample.c +++ b/src/sample.c @@ -861,7 +861,9 @@ sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = { * Parse a sample expression configuration: * fetch keyword followed by format conversion keywords. * Returns a pointer on allocated sample expression structure. - * The caller must have set al->ctx. + * is an arg_list serving as a list head to report missing dependencies. + * It may be NULL if such dependencies are not allowed. Otherwise, the caller + * must have set al->ctx if al is set. * If is non-nul, it will be set to the first unparsed character * (which may be the final '\0') on success. If it is nul, the expression * must be properly terminated by a '\0' otherwise an error is reported. @@ -920,8 +922,10 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in * this allows it to automatically create entries for mandatory * implicit arguments (eg: local proxy name). */ - al->kw = expr->fetch->kw; - al->conv = NULL; + if (al) { + al->kw = expr->fetch->kw; + al->conv = NULL; + } if (make_arg_list(endw, -1, fetch->arg_mask, &expr->arg_p, err_msg, &endt, &err_arg, al) < 0) { memprintf(err_msg, "fetch method '%s' : %s", fkw, *err_msg); goto out_error; @@ -1021,8 +1025,10 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in LIST_APPEND(&(expr->conv_exprs), &(conv_expr->list)); conv_expr->conv = conv; - al->kw = expr->fetch->kw; - al->conv = conv_expr->conv->kw; + if (al) { + al->kw = expr->fetch->kw; + al->conv = conv_expr->conv->kw; + } argcnt = make_arg_list(endw, -1, conv->arg_mask, &conv_expr->arg_p, err_msg, &endt, &err_arg, al); if (argcnt < 0) { memprintf(err_msg, "invalid arg %d in converter '%s' : %s", err_arg+1, ckw, *err_msg);