From: Aurelien DARRAGON Date: Wed, 23 Aug 2023 15:22:37 +0000 (+0200) Subject: MINOR: sample: add sample_process_cnv() function X-Git-Tag: v2.9-dev8~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=72513447488275a0ad7f78416e31a2368f607b02;p=thirdparty%2Fhaproxy.git MINOR: sample: add sample_process_cnv() function split sample_process() in 2 parts in order to be able to only process the converter part of a sample expression from an existing input sample struct passed as parameter. --- diff --git a/include/haproxy/sample.h b/include/haproxy/sample.h index a941a65de2..7e05e78400 100644 --- a/include/haproxy/sample.h +++ b/include/haproxy/sample.h @@ -39,6 +39,7 @@ struct sample_conv *find_sample_conv(const char *kw, int len); struct sample *sample_process(struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt, struct sample_expr *expr, struct sample *p); +int sample_process_cnv(struct sample_expr *expr, struct sample *p); struct sample *sample_fetch_as_type(struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt, struct sample_expr *expr, int smp_type); diff --git a/src/sample.c b/src/sample.c index 65985e32b8..f1705ea47d 100644 --- a/src/sample.c +++ b/src/sample.c @@ -1285,6 +1285,39 @@ out_error: goto out; } +/* + * Helper function to process the converter list of a given sample expression + * using the sample

(which is assumed to be properly initialized) + * as input. + * + * Returns 1 on success and 0 on failure. + */ +int sample_process_cnv(struct sample_expr *expr, struct sample *p) +{ + struct sample_conv_expr *conv_expr; + + list_for_each_entry(conv_expr, &expr->conv_exprs, list) { + /* we want to ensure that p->type can be casted into + * conv_expr->conv->in_type. We have 3 possibilities : + * - NULL => not castable. + * - c_none => nothing to do (let's optimize it) + * - other => apply cast and prepare to fail + */ + if (!sample_casts[p->data.type][conv_expr->conv->in_type]) + return 0; + + if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none && + !sample_casts[p->data.type][conv_expr->conv->in_type](p)) + return 0; + + /* OK cast succeeded */ + + if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private)) + return 0; + } + return 1; +} + /* * Process a fetch + format conversion of defined by the sample expression * on request or response considering the parameter. @@ -1313,8 +1346,6 @@ struct sample *sample_process(struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt, struct sample_expr *expr, struct sample *p) { - struct sample_conv_expr *conv_expr; - if (p == NULL) { p = &temp_smp; memset(p, 0, sizeof(*p)); @@ -1324,25 +1355,8 @@ struct sample *sample_process(struct proxy *px, struct session *sess, if (!expr->fetch->process(expr->arg_p, p, expr->fetch->kw, expr->fetch->private)) return NULL; - list_for_each_entry(conv_expr, &expr->conv_exprs, list) { - /* we want to ensure that p->type can be casted into - * conv_expr->conv->in_type. We have 3 possibilities : - * - NULL => not castable. - * - c_none => nothing to do (let's optimize it) - * - other => apply cast and prepare to fail - */ - if (!sample_casts[p->data.type][conv_expr->conv->in_type]) - return NULL; - - if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none && - !sample_casts[p->data.type][conv_expr->conv->in_type](p)) - return NULL; - - /* OK cast succeeded */ - - if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private)) - return NULL; - } + if (!sample_process_cnv(expr, p)) + return NULL; return p; }