mirror of
https://github.com/rsyslog/rsyslog.git
synced 2026-08-24 19:24:14 +02:00
rainerscript: warn on constant AND/OR operand at parse time
Why: The AND/OR constant-operand warning (issue #1046) ran in the optimizer, after constFoldCmp(). Legitimate constant comparisons - typically backtick-expanded environment feature flags, e.g. `echo $FLAG` == "on" - fold to a constant operand and were wrongly flagged. The warning also ran after yyparse(), so it reported the last line of the master config instead of the offending expression. Impact: Comparisons that constant-fold to a constant no longer warn. The bare literal mistake ($msg contains "a" or "b") still warns, now at the correct file and line. Technical Overview: Move the check from cnfexprOptimize_AND_OR() to cnfexprNew(), where the operand is still the comparison node as written and cnfcurrfn/yylineno are accurate. A backtick used directly as a bare boolean operand still warns, as intended: after lexer expansion it is identical to a hand-written literal, exactly the pattern the warning targets. Regression test extended with a negative constant-fold case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e22428a2fb
commit
6d8e3b9db9
@ -1413,6 +1413,26 @@ void cnfobjPrint(struct cnfobj *o) {
|
||||
struct cnfexpr *cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r) {
|
||||
struct cnfexpr *expr;
|
||||
|
||||
/* Warn on bare constant AND/OR operands as written in the config, e.g.
|
||||
* `$msg contains "a" or "b"` (issue #1046). This must happen here, at
|
||||
* construction time, rather than in the optimizer: constFoldCmp() later
|
||||
* reduces legitimate constant comparisons (typically backtick-expanded
|
||||
* environment variables, e.g. `echo $FLAG` == "on") to constant operands,
|
||||
* which must not warn. At this point such an operand is still a comparison
|
||||
* node, and cnfcurrfn/yylineno still point at the offending expression, so
|
||||
* the reported file and line are accurate.
|
||||
*/
|
||||
if (nodetype == AND || nodetype == OR) {
|
||||
if (l != NULL && (l->nodetype == 'N' || l->nodetype == 'S')) {
|
||||
parser_warnmsg("boolean operator '%s' has constant left operand; did you mean to repeat the comparison?",
|
||||
tokenToString(nodetype));
|
||||
}
|
||||
if (r != NULL && (r->nodetype == 'N' || r->nodetype == 'S')) {
|
||||
parser_warnmsg("boolean operator '%s' has constant right operand; did you mean to repeat the comparison?",
|
||||
tokenToString(nodetype));
|
||||
}
|
||||
}
|
||||
|
||||
/* optimize some constructs during parsing */
|
||||
if (nodetype == 'M' && r->nodetype == 'N') {
|
||||
((struct cnfnumval *)r)->val *= -1;
|
||||
@ -5627,15 +5647,9 @@ static struct cnfexpr *cnfexprOptimize_NOT(struct cnfexpr *expr) {
|
||||
static struct cnfexpr *cnfexprOptimize_AND_OR(struct cnfexpr *expr) {
|
||||
struct cnffunc *funcl, *funcr;
|
||||
|
||||
if (expr->l->nodetype == 'N' || expr->l->nodetype == 'S') {
|
||||
parser_warnmsg("boolean operator '%s' has constant left operand; did you mean to repeat the comparison?",
|
||||
tokenToString(expr->nodetype));
|
||||
}
|
||||
if (expr->r->nodetype == 'N' || expr->r->nodetype == 'S') {
|
||||
parser_warnmsg("boolean operator '%s' has constant right operand; did you mean to repeat the comparison?",
|
||||
tokenToString(expr->nodetype));
|
||||
}
|
||||
|
||||
/* the constant-operand warning is emitted at construction time in
|
||||
* cnfexprNew(); see the comment there for why it cannot live here.
|
||||
*/
|
||||
if (expr->l->nodetype == 'F') {
|
||||
if (expr->r->nodetype == 'F') {
|
||||
funcl = (struct cnffunc *)expr->l;
|
||||
|
||||
@ -1,16 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Verify that a common RainerScript boolean mistake logs a config warning:
|
||||
# `$msg contains "a" or "b"` keeps historical truthiness semantics, but the
|
||||
# bare string literal is probably a missing repeated comparison. The oracle is
|
||||
# rsyslogd config-check output because the warning is emitted while optimizing
|
||||
# the parsed configuration, before normal message routing is relevant.
|
||||
# bare string literal is probably a missing repeated comparison. The warning
|
||||
# must only fire on constants as written: comparisons that merely constant-fold
|
||||
# to a constant (e.g. backtick-expanded environment variables) are legitimate
|
||||
# and must stay silent. The oracle is rsyslogd config-check output.
|
||||
. ${srcdir:=.}/diag.sh init
|
||||
|
||||
export MY_FEATURE="on"
|
||||
generate_conf
|
||||
add_conf '
|
||||
if $msg contains "alpha" or "beta" then {
|
||||
action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
|
||||
}
|
||||
if `echo $MY_FEATURE` == "on" and $msg contains "gamma" then {
|
||||
action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
|
||||
}
|
||||
'
|
||||
|
||||
export RS_REDIR=">${RSYSLOG_DYNNAME}.rsyslog.log 2>&1"
|
||||
@ -18,4 +23,5 @@ rsyslogd_config_check
|
||||
unset RS_REDIR
|
||||
|
||||
content_check "boolean operator 'OR' has constant right operand" "${RSYSLOG_DYNNAME}.rsyslog.log"
|
||||
check_not_present "boolean operator 'AND' has constant" "${RSYSLOG_DYNNAME}.rsyslog.log"
|
||||
exit_test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user