/* Parse an ACL expression starting at <args>[0], and return it. If <err> 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. <al> 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 :
* <subject> [<value>...]
* 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) {
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.",
* an anonymous one and it won't be merged with any other one. If <err> is not
* NULL, it will be filled with an appropriate error. This pointer must be
* freeable or NULL. <al> is the arg_list serving as a head for unresolved
- * dependencies.
+ * dependencies. It may be NULL if such dependencies are not allowed.
*
* args syntax: <aclname> <acl_expr>
*/
* If <known_acl> is not NULL, the ACL will be queued at its tail. If <err> is
* not NULL, it will be filled with an error message if an error occurs. This
* pointer must be freeable or NULL. <al> 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,
* <err> 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 <al> 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,
* 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 <al>, 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 <err_msg> 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 <end_ptr>, which is the first character considered as not
- * being part of the arg list. The input string ends on the first between <len>
- * characters (when len is positive) or the first NUL character. Placing -1 in
- * <len> will make it virtually unbounded (~2GB long strings).
+ * entries. <al> 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 <err_msg> 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 <end_ptr>, which is the first character considered as not being part
+ * of the arg list. The input string ends on the first between <len> characters
+ * (when len is positive) or the first NUL character. Placing -1 in <len> 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,
/* 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);
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.
* 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.
+ * <al> 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 <endptr> 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.
* 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;
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);