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 *cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r) {
|
||||||
struct cnfexpr *expr;
|
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 */
|
/* optimize some constructs during parsing */
|
||||||
if (nodetype == 'M' && r->nodetype == 'N') {
|
if (nodetype == 'M' && r->nodetype == 'N') {
|
||||||
((struct cnfnumval *)r)->val *= -1;
|
((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) {
|
static struct cnfexpr *cnfexprOptimize_AND_OR(struct cnfexpr *expr) {
|
||||||
struct cnffunc *funcl, *funcr;
|
struct cnffunc *funcl, *funcr;
|
||||||
|
|
||||||
if (expr->l->nodetype == 'N' || expr->l->nodetype == 'S') {
|
/* the constant-operand warning is emitted at construction time in
|
||||||
parser_warnmsg("boolean operator '%s' has constant left operand; did you mean to repeat the comparison?",
|
* cnfexprNew(); see the comment there for why it cannot live here.
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expr->l->nodetype == 'F') {
|
if (expr->l->nodetype == 'F') {
|
||||||
if (expr->r->nodetype == 'F') {
|
if (expr->r->nodetype == 'F') {
|
||||||
funcl = (struct cnffunc *)expr->l;
|
funcl = (struct cnffunc *)expr->l;
|
||||||
|
|||||||
@ -1,16 +1,21 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Verify that a common RainerScript boolean mistake logs a config warning:
|
# Verify that a common RainerScript boolean mistake logs a config warning:
|
||||||
# `$msg contains "a" or "b"` keeps historical truthiness semantics, but the
|
# `$msg contains "a" or "b"` keeps historical truthiness semantics, but the
|
||||||
# bare string literal is probably a missing repeated comparison. The oracle is
|
# bare string literal is probably a missing repeated comparison. The warning
|
||||||
# rsyslogd config-check output because the warning is emitted while optimizing
|
# must only fire on constants as written: comparisons that merely constant-fold
|
||||||
# the parsed configuration, before normal message routing is relevant.
|
# 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
|
. ${srcdir:=.}/diag.sh init
|
||||||
|
|
||||||
|
export MY_FEATURE="on"
|
||||||
generate_conf
|
generate_conf
|
||||||
add_conf '
|
add_conf '
|
||||||
if $msg contains "alpha" or "beta" then {
|
if $msg contains "alpha" or "beta" then {
|
||||||
action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
|
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"
|
export RS_REDIR=">${RSYSLOG_DYNNAME}.rsyslog.log 2>&1"
|
||||||
@ -18,4 +23,5 @@ rsyslogd_config_check
|
|||||||
unset RS_REDIR
|
unset RS_REDIR
|
||||||
|
|
||||||
content_check "boolean operator 'OR' has constant right operand" "${RSYSLOG_DYNNAME}.rsyslog.log"
|
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
|
exit_test
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user