From: Adis Nezirovic Date: Wed, 22 Jan 2020 15:50:27 +0000 (+0100) Subject: MINOR: cli: Report location of errors or any extra data for "show table" X-Git-Tag: v2.2-dev2~105 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d0142e7224e874380b3f2c5f651557ffe74155c0;p=thirdparty%2Fhaproxy.git MINOR: cli: Report location of errors or any extra data for "show table" When using multiple filters with "show table", it can be useful to report which filter entry failed > show table MY_TABLE data.gpc0 gt 0 data.gpc0a lt 1000 Filter entry #2: Unknown data type > show table MY_TABLE data.gpc0 gt 0 data.gpc0 lt 1000a Filter entry #2: Require a valid integer value to compare against We now also catch garbage data after the filter > show table MY_TABLE data.gpc0 gt 0 data.gpc0 lt 1000 data.gpc0 gt 1\ data.gpc0 gt 10 a Detected extra data in filter, 16th word of input, after '10' Even before multi-filter feature we've also silently accepted garbage after the input, hiding potential bugs > show table MY_TABLE data.gpc0 gt 0 data.gpc0 or > show table MY_TABLE data.gpc0 gt 0 a In both cases, only first filter entry would be used, silently ignoring extra filter entry or garbage data. Last, but not the least, it is now possible to detect multi-filter feature from cli with something like the following: > show table MY_TABLE data.blah Filter entry #1: Unknown data type --- diff --git a/src/stick_table.c b/src/stick_table.c index 1b397e59e4..1e7d4f3a86 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -3601,6 +3601,7 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args) static int table_prepare_data_request(struct appctx *appctx, char **args) { int i; + char *err = NULL; if (appctx->ctx.table.action != STK_CLI_ACT_SHOW && appctx->ctx.table.action != STK_CLI_ACT_CLR) return cli_err(appctx, "content-based lookup is only supported with the \"show\" and \"clear\" actions\n"); @@ -3611,17 +3612,21 @@ static int table_prepare_data_request(struct appctx *appctx, char **args) /* condition on stored data value */ appctx->ctx.table.data_type[i] = stktable_get_data_type(args[3+3*i] + 5); if (appctx->ctx.table.data_type[i] < 0) - return cli_err(appctx, "Unknown data type\n"); + return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1)); if (!((struct stktable *)appctx->ctx.table.target)->data_ofs[appctx->ctx.table.data_type[i]]) - return cli_err(appctx, "Data type not stored in this table\n"); + return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Data type not stored in this table\n", i + 1)); appctx->ctx.table.data_op[i] = get_std_op(args[4+3*i]); if (appctx->ctx.table.data_op[i] < 0) - return cli_err(appctx, "Require and operator among \"eq\", \"ne\", \"le\", \"ge\", \"lt\", \"gt\"\n"); + return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require and operator among \"eq\", \"ne\", \"le\", \"ge\", \"lt\", \"gt\"\n", i + 1)); if (!*args[5+3*i] || strl2llrc(args[5+3*i], strlen(args[5+3*i]), &appctx->ctx.table.value[i]) != 0) - return cli_err(appctx, "Require a valid integer value to compare against\n"); + return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require a valid integer value to compare against\n", i + 1)); + } + + if (*args[3+3*i]) { + return cli_dynerr(appctx, memprintf(&err, "Detected extra data in filter, %ith word of input, after '%s'\n", 3+3*i + 1, args[2+3*i])); } /* OK we're done, all the fields are set */