They are unused in Wikimedia code (finally).
Change-Id: I74c81d950d992552d3edf184b5eecc46e5e2c567
Depends-On: I62533e21d2bc1a22c3fcba4c7c650ca9d95700ef
Depends-On: I95ce9897d89213e358c436135278b729f0adc3a2
Add a space between the checkbox (shown for users who can hide abuse
filter entries) and the timestamp so that it looks nicer.
Change-Id: I6e495f8cb56ad8f0b53f06d2aecb8ac34b16ff25
A new core facility written for this use case.
Bug: T310662
Depends-On: I26b1cdba0a06ad16ad8bb71b455e1b6180924d17
Change-Id: I2b902d034a8c3308c0ba9878b69e873ca8fbda52
Add the ListToggle provided in core's ListToggle.php to
Special:AbuseLog when a list of abuse filter entries are being
shown and the user can hide abuse filter entries. This will allow
them to select multiple checkboxes to hide at once (without having
to shift and selecting the first and last).
Bug: T311954
Change-Id: I1aa4fa3fa7016a5d9ae4a904c151011743d2c8ed
Move most stuff from the pager to the view class to untangle
circular dependency. Declare class properties as private.
Leave input validation to the form.
Change-Id: Ia8b1a9d08af9c0cac23b34f6bbbe2c44d01f6c8c
In action=abusefilterunblockautopromote, leave UserIdentity
instantiation to the parent. Note that this changes the "code"
in the response from "baduser_user" to "baduser".
Change-Id: I97d2bf3fa3c5486e461823f840cad2763e1bcfea
Almost all callers already provide an Authority in the form
of a User object, so mostly just need to change the typehints
Depends-On: I58661943c7e1acb6ff09798ee1a30be0fde3f459
Change-Id: I2ad86859c8194c14d7331f58db62b7cff4698085
Prevent invalid assignments to properties. On
Special:AbuseFilter/test/123, handle when id of
a non-existing filter was provided. Allow '0'
as user and title on Special:AbuseLog and
Special:AbuseFilter/test.
Change-Id: I196ae62b165d1a60babaf4fe6bd733aa52be1726
These are apparently the only two variables for which we can
quickly determine their value in such simple way.
Later, we can also try it for recent contributions.
Bug: T102944
Change-Id: Iecfa9e5c5ba8c078691334b676cc6f289790cb74
This was most definitely my intention when I introduced the concept of
"generic vars", so it's a bit surprising to discover, 3.5 years later,
that the timestamp isn't computed there.
Also make the timestamp always be a string for consistency, since that's
the type documented on mw.org. I've manually checked all filters on
Wikimedia wikis using the timestamp variable, and added explicit int
casts where needed (although I think they'd still work due to implicit
casts).
Change-Id: Ib6e15225dd95c2eead7e48c200d203d6918e0c18
The "substr( $line, 0, 1 )" expression has already assumed
the prefix has length 1. Therefore, it's pointless
to compute its length later. The assumption does hold,
the only two prefixes the code works with are '+' and '-'.
Not changing the check to use str_starts_with now, because
it was suggested in I113a8d052b6845852c15969a2f0e6fbbe3e9f8d9
that this shouldn't be done for performance-sensitive code
at least until we are on PHP 8.
Change-Id: I00cb2fc50ed534bb2bbef3ee1e5f6f466afeeb27
We want to make sure that all parameters are valid regardless of whether
there's a match.
Also make the minimum number of parameters = 2, so it's easier to switch
between this function and ip_in_range.
Change-Id: I141558a7ef4533485e315b3d93ea9b64f0959db7
Added support for ip_in_ranges which allow multiple ranges to be
checked at the same time. If the IP is in any of the ranges, the
function returns true.
Bug: T305017
Change-Id: Ic75c87ecd4cacf47ce2ff1b04173405230ff81d0
Clean up the existing code a bit before refactoring to be reusable
for a diff button in the edit form.
Includes:
* use the Html class rather than the Xml class for building the display html, and avoid manual
html strings
* replace formatVersionLink() with getVersionHeading() to reduce duplication in the handling of
the headings for the old and new versions, and in the process fix the name used as a parameter to
the old version heading (should be the old version editor, not the new version editor)
* rename some parameters for clarity
* organization and other cleanup
Bug: T180954
Change-Id: I1c02f407e72789a871a23b0d4a279a5c341b1e93
Before the information if a filter was new was stored in 2 places:
In the bool $isNew and in the two variables $filter and $newID.
$newID was especially confusing because it was used for both old and
new ids.
Change-Id: I15bdf36c96c8d86a37f305aab2647f7d57bc2bf1
- Define it with the extension.json key, instead of using the
registration callback
- Inject the services it needs
- Replace direct User instantiation with UserFactory
- Move log subtypes to extension.json as well
Change-Id: I86a761c7fa844b1f417b974798373622a15f6411
The check was not consistent and the code could still crash
when $oldContent was null. RevisionRecord:getContent only
returns null when audience check fails, but we don't ask
for that.
Change-Id: Id64646a6762167f552e104f623130bedc6b2dd18
The getLocalURL() method can return url with query string when
wgArticlePath is configured to do so, and query string of GET form
would be ignored by browsers.
The setAction() method is problematic (T285464 and above) and hard to
warn the wrong usage. I'm going to go through and fix every use case,
and finally deprecate it.
Change-Id: I66b634f0cc996be3d7048d410b46fe77c88f9879
This is a breaking change for the API: 'hidden' is now either true or
false, depending on afl_deleted. 'implicit' is no longer a possible
value, the caller should compute it instead if necessary.
Then simplify the remaining usage of isHidden, using a temporary private
method.
Bug: T291718
Change-Id: I97b5195d306c35ddca3f071d9ff4d896f9fd5c8d
Use setTitle() instead of setAction(), T285464.
HTMLForm would set edit token for post form, use setTokenSalt() to amend.
HTMLForm would fetch user input value from the request itself, since
the two form shared the same field name, the 'default' params assigned
are unfunctional.
HTMLForm would prefix descriptor keys with 'wp' as the default name
of generated input fields, make use of this feature.
Bug: T285464
Change-Id: I2cc3c1d042998b65df5ee51f0715fe25a5e18e72
Introduce shorter methods, one for each steps, so that it's easier to
understand what the code is doing and figure out if the order makes
sense. The ConsequencesExecutor test is now a proper unit test. Also
simplify AbuseFilterConsequencesTest, removing old/wrong logic and
fixing two expected values that were actually wrong (but worked because
of the aforementioned wrong logic).
The only functional changes should be:
- We pick the longest block *after* checking the ConsequenceDisabler
consequences, so e.g. if a filter has a long block + warn and another
filter has a shorter block, we still keep the second one if warn will
disable the block.
- Remove disallow in presence of dangerous actions after checking
ConsequenceDisabler's and deduplicating blocks. Otherwise we may
remove disallow for filters where block (etc.) doesn't end up being
disabled. We may also want to consider not removing disallow at all,
now that messages are customizable.
Bug: T303059
Change-Id: If00adbf2056758222eaaea70b16d3b4f89502c20
This was likely a rebase artefact or something: the 'implode' was meant
to be called with two parameters as usual. Currently, the parameters are
simply concatenated which makes the logs quite hard to read.
Change-Id: I84f9a7cb05e210f60a791d513dfb5b74fa7dfb8a
- Use a /64 range for IPv6 instead of /16.
- Fix a curious and serious bug for IPv6, where grouping by range
would only use the first (!) number of the IP address, due to the
'v6-' prefix returned by IP::toHex.
- Fail hard if the identifier is unknown -- it's not something that's
supposed to happen.
- Include the type name in each identifier, instead of prefixing all
type names to all identifiers. This makes it easier to understand the
parts of the key.
- Test the whole lot.
Bug: T211101
Change-Id: I54c4209f2f0d5a4c5e7b81bed240ca3e28a2ded7
List which actions were disabled, or explicitly say that no actions were
disabled if that's the case. Also avoid the word "throttle" in messages
as it may be hard to translate. Also don't suggest optimizations to the
filter conditions -- unoptimized rules have nothing to do with a filter
being throttled.
Bug: T200036
Change-Id: Id989fb185453d068b7685241ee49189a2df67b5f
This is a plain value object that represents the action being filtered,
replacing associative arrays that were being used up to this point.
We should now check whether it's possible to make it not require an
accountname (which complicates things), and then use it in related
classes as well, e.g. Parameters.
Change-Id: I9550c14819b600c97c46b632cc1c2d447972d69c
The existing filters on WMF wikis has been changes such that calls
to rmspecials() are now rmspecials(rmwhitespace()) to ensure no change
is made in behaviour. Filter admins can change this back if filter is
not meant to trigger when part of the input is contains spaces.
Bug: T263024
Change-Id: Idde09b50fb8eda357afbedc1199a5483fa8217c1
Replaced with the more readable ::disableClientCache() method, added
in 1.38. Minimum MW version bumped to match.
Depends-On: I7c89e20528a0d91173f0edcb997dcae631935ee5
Change-Id: I91d0b8e8f69a2d309b6fc61e13bfb5d86dc0218d
old_links and all_links are an array. Casting
them to string and then splitting by newlines
is a no-op.
Change-Id: I05c69f14e981ac2842032e7db888f4841d6b48b7
We should avoid using ObjectCache directly and use services instead. On
top of that, db-replicated writes to objectcache table that should be
avoided and it's now blocking schema changes.
This should go to MainStash.
Bug: T272512
Change-Id: I9c76399ec4c0ea6644f9ca1b4536428052e5ac38
These are not necessarily old links, the new links
can also be retrieved using this code path.
Also print debug messages before the code execution.
Change-Id: I1a85bb7b5a2af4fe514625d2236cf92f15daf304
The special page itself is a MessageLocalizer
SpecialPage::getContext on constructor results in global state
Change-Id: I6a3dd263dbe02111aea65a087ce69a5a191f63fc
The report is now generated in ParserOutput, not Parser, meaning we can
simply avoid passing the `enableLimitReport` option (off by default) if
we don't want the report to be there.
Depends-On: I154c0a77a5b0287b5572614d56339fb57ac56c33
Change-Id: I8cdab35c475f10433234ddb55b5e6a0cc8109498
Note that this doesn't have to be applied in WMF prod, since the indexes
are already correct there.
Bug: T291725
Change-Id: I7fcee0581f469e0d7ada43d1f30f31061c5bf5c0
This does the same as before, replacing \r\n as well as \r with \n.
Additionally the new method applies an rtrim() on both strings. I
believe this is even a good thing. It possibly removes irrelevant
noise from the diff.
Change-Id: I584740a24e6b25bbcbc928c2369f09b785a485c8
On second thought, no need to keep the migration script now, since it's
unusable anyway.
Also remove an usage in SpecialAbuseLog, likely a rebase artefact.
Change-Id: I938924b3617ef30046d8317e68a101ed2c1883d3
This replaces the previous pattern of callers having to use
RevisionLookup if the result was 'implicit'. Also, in some cases where
we were just hiding things if the visibility was !== true, properly
handle the implicit case by using the new method. Make the new method
return string constants rather than bool|string.
The new method also fixes some potential info leaks which happened when
the row was hidden, the user could view suppressed AbuseLog entries, but
the associated revision was also deleted and the user couldn't see it
(this shouldn't be relevant for WMF wikis since AF deletion is
oversight-level).
Also add a bunch of tests for the various cases to ensure we don't
regress again.
Bug: T261532
Change-Id: I929f865acf5d207b739cb3af043f70cb59243ee0
ParserStatus is now more lightweight, and doesn't know about "result"
and "from cache". Instead, it has an isValid() method which is merely a
shorthand for checking whether getException() is null.
Introduce a child class, RuleCheckerStatus, which knows about result and
cache and can be (un)serialized.
This removes the ambiguity of the $result field, and helps the
transition to a new RuleChecker class.
Change-Id: I0dac7ab4febbfdabe72596631db630411d967ab5
Something somewhere is leaving error_reporting in a dirty state
causing AbuseFilter's ConsequencesExecutorTest case to fail for
the core change Ic9fee6cdd88001025.
Per T253461, we're meant to eventually remove this anyway, so might
as well remove it in areas that are known to get it wrong somehow.
Change-Id: I2a665f09a357f2f2cc258d8c4011d49a7ab9c13b
The old parser now has the correct name "Evaluator", so the
ParserFactory name was outdated. Additionally, the plan is to create a
new RuleChecker class, acting as a facade for the different
parsing-related stages (lexer, parser, evaluator, etc.), which is what
most if not all callers should use. The RuleCheckerFactory still returns
a FilterEvaluator for now.
Also, "Parser" is a specific term defining *how* things happen
internally, whereas "RuleChecker" describes *what* callers should expect
from the new class.
Change-Id: I25b47a162d933c1e385175aae715ca38872b1442
Remove unnecessary setters, injecting everything in the constructor.
These were leftovers from before the introduction of ParserFactory.
Remove public access to the conds used, include the information inside
the returned ParserStatus instead, and consequently simplify callers.
Change-Id: I0a30e044877c6c858af3ff73f819d5ec7c4cc769
So that the method can be typehinted in core.
Also add phan-var to fix broken master build due to typehint additions
in core.
Change-Id: I4a072e00ffeeb437753fc3d3c1f15de9929df510
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
Create a dedicated "Exception" sub-namespace and remove the "AFP"
prefix, a leftover from the pre-namespace era.
Change-Id: I7e5fded9316d8b7d1628bc1a6ba8b1879ac901e1
Previously, for non-newly-created pages, AbuseFilter would get the text
for filtering twice: once in AbuseFilterHooks::filterEdit(), and then
again in RunVariableGenerator::getEditTextForFiltering(). (Plus another
call for the text of the previous revision.) The first copy of the text
is only passed into RunVariableGenerator::getEditVars(), and there only
used if the title doesn’t exist, otherwise it’s overwritten with the
second copy. Instead, let’s make AbuseFilterHooks not get the text at
all, and only get the text from the content when we actually need it
(the content is new).
Change-Id: Id12430fa6ba4643113b945e0d0c01b9c0ee1742f
This reverts commit 15fc159cb1.
Reason for revert: this is breaking the addition of rev ids to filter
hits after edits are saved. I suspect this is because the context wikipage
is for a different title than the one being edited, though I'm not sure
way - regardless, testing on patchdemo shows that with this revert
is applied, rev ids are once again added to filter hits.
Bug: T286140
Change-Id: I3ab6324a73050154cef1c20a2bf8307eb11eea2d
If the content language is English and the message is invalid as
a username, or the content language is not English and both the
content language version and the English version are invalid, the
user in FilterUser would not be created - now, avoid the onwiki
version of the English message in the fallback, so it could only
be invalid if the default in the i18n files was invalid.
Bug: T284364
Change-Id: I9e9f44b7663e810de70fb9ac7f6760f83dd4895b