MINOR: sample: introduce c_pseudo() conv function

This function is used for ANY=>!ANY conversions in the compatibility
matrix to help differentiate between real NOOP (c_none) and pseudo
conversions that are theorically supported at config parse time but can
never occur at runtime,. That is, to explicit the fact that actual related
runtime operations (e.g.: ANY->IPV4) are not NOOP since they might require
some conversion to be performed depending on the input type.

When checking the conf we don't know the effective out types so
cast[pseudo type][pseudo type] is allowed in the compatibility matrix,
but at runtime we only expect cast[real type][(real type || pseudo type)]
because fetches and converters may not emit pseudo types, thus using
c_none() everywhere was too ambiguous.

The process will crash if c_pseudo() is invoked to help catch bugs:
crashing here means that a pseudo type has been encountered on a
converter's input at runtime (because it was emitted earlier in the
chain), which is not supported and results from a broken sample fetch
or converter implementation. (pseudo types may only be used as out_type
in sample definitions for compatibility checks at parsing time)
This commit is contained in:
Aurelien DARRAGON 2023-06-06 19:03:45 +02:00 committed by Christopher Faulet
parent 58bbe41cb8
commit 30cd137d3f
3 changed files with 25 additions and 3 deletions

View File

@ -26,9 +26,14 @@
#include <haproxy/api-t.h>
#include <haproxy/sample_data-t.h>
/* input and output sample types */
/* input and output sample types
*
* Some of them are pseudo types which means that they can be used for
* in_type and out_type in sample (fetches/conv) definitions (they serve as
* compatibility and conversion hints) but they cannot be emitted at runtime.
*/
enum {
SMP_T_ANY = 0, /* any type */
SMP_T_ANY = 0, /* pseudo type: any type */
SMP_T_BOOL, /* boolean */
SMP_T_SINT, /* signed 64bits integer type */
SMP_T_ADDR, /* ipv4 or ipv6, only used for input type compatibility */

View File

@ -59,6 +59,7 @@ int smp_resolve_args(struct proxy *p, char **err);
int smp_check_date_unit(struct arg *args, char **err);
int smp_expr_output_type(struct sample_expr *expr);
int c_none(struct sample *smp);
int c_pseudo(struct sample *smp);
int smp_dup(struct sample *smp);
/*

View File

@ -864,6 +864,22 @@ int c_none(struct sample *smp)
return 1;
}
/* special converter function used by pseudo types in the compatibility matrix
* to inform that the conversion is theorically allowed at parsing time.
*
* However, being a pseudo type, it may not be emitted by fetches or converters
* so this function should never be called. If this is the case, then it means
* that a pseudo type has been used as a final output type at runtime, which is
* considered as a bug and should be fixed. To help spot this kind of bug, the
* process will crash in this case.
*/
int c_pseudo(struct sample *smp)
{
ABORT_NOW(); // die loudly
/* never reached */
return 0;
}
static int c_str2int(struct sample *smp)
{
const char *str;
@ -978,7 +994,7 @@ static int c_bool2bin(struct sample *smp)
sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
/* to: ANY BOOL SINT ADDR IPV4 IPV6 STR BIN METH */
/* from: ANY */ { c_none, c_none, c_none, c_none, c_none, c_none, c_none, c_none, c_none, },
/* from: ANY */ { c_none, c_pseudo, c_pseudo, c_pseudo, c_pseudo, c_pseudo, c_pseudo, c_pseudo, c_pseudo, },
/* BOOL */ { c_none, c_none, c_none, NULL, NULL, NULL, c_int2str, c_bool2bin, NULL, },
/* SINT */ { c_none, c_none, c_none, c_int2ip, c_int2ip, c_int2ipv6, c_int2str, c_int2bin, NULL, },
/* ADDR */ { c_none, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, },