mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter.git
synced 2024-11-15 10:15:24 +00:00
320e3d696f
This commit adds a class AFPSyntaxChecker which can statically analyze a filter code to detect the following errors: - unbound variables (which comes in two modes: conservative and liberal, default to conservative) - unused variables (disabled by default for compatibilty) - assignment on built-in identifiers - function application's arity mismatch - function application's invalid function name - non-string literal in the first argument of set / set_var The existing parser and evaluator are modified as follows: - The new (caching) evaluator no longer needs to perform variable hoisting at runtime. - Note that for array assignment, this changes the semantics. - The new parser is more lenient, reducing parsing errors. The static analyzer will catch these errors instead, allowing us to give a much better error message and reduces the complexity of the parser. * The parser now allows function name to be any identifier. * The parser now allows arity mismatch to occur. * The parser now allows the first argument of set to be any expression. Concretely, obvious changes that users will see are: 1. a := [1]; false & (a[] := 2); a[0] === 1 would evaluate to true, while it used to evaluate to the undefined value due to hoisting 2. f(1) will now error with 'f is not a valid function' as opposed to 'Unexpected "T_BRACE"' 3. length will now error with 'Illegal use of built-in identifier "length"' as opposed to 'Expected a (' Appendix: conservative and liberal mode The conservative mode is completely compatible with the current evaluator. That is, false & (a := 1); a will not deem `a` as unbound, though this is actually undesirable because `a` would then be bound to the troublesome undefined value. The liberal mode rejects the above pattern by deeming `a` as unbound. However, it also rejects true & (a := 1); a even though (a := 1) is always executed. Since there are several filters in Wikimedia projects that rely on this behavior, we default the mode to conservative for now. Note that even the liberal mode doesn't really respect lexical scope appeared in some other programming languages (see also T234690). For instance: (if true then (a := 1) else (a := 2) end); a would be accepted by the liberal checker, even though under lexical scope, `a` would be unbound. However, it is unlikely that lexical scope will be suitable for the filter language, as most filters in Wikimedia projects that have user-defined variable do violate lexical scope. Bug: T260903 Bug: T238709 Bug: T237610 Bug: T234690 Bug: T231536 Change-Id: Ic6d030503e554933f8d220c6f87b680505918ae2 |
||
---|---|---|
.. | ||
Exception | ||
AbuseFilterCachingParser.php | ||
AbuseFilterTokenizer.php | ||
AFPData.php | ||
AFPParserState.php | ||
AFPSyntaxTree.php | ||
AFPToken.php | ||
AFPTransitionBase.php | ||
AFPTreeNode.php | ||
AFPTreeParser.php | ||
ParserFactory.php | ||
ParserStatus.php | ||
SyntaxChecker.php |