Commit graph

666 commits

Author SHA1 Message Date
Peter Wangai 00ac95decd selenium: Refactor WebdriverIO tests from sync to async mode
WebdriverIO has dropped support of sync mode, hence changed to async.

Update npm packages: @wdio/*, wdio-mediawiki
because async mode needs at least @wdio v7.9.

Remove npm packages: @wdio/dot-reporter and @wdio/sync.

Bug: T300790
Change-Id: Ifcc95a8c7e47ba4513f6910620ecce83e1ead15a
2023-03-28 17:50:18 +03:00
Matěj Suchánek 0628dbdab6 Add tests for extension.json and services
Change-Id: Ie83e4a85a408e1ba1d2cc827c4bf353bdd5500df
2023-03-28 09:35:02 +02:00
jenkins-bot 290dd70bb2 Merge "Replace deprecated database object access methods" 2023-03-27 09:11:46 +00:00
Matěj Suchánek bb78cb0a56 Use actor table in AbuseFilter
This patch migrates abuse_filter and abuse_filter_history tables
to new actor schema.

MigrateActorsAF was copy-pasted from core's
maintenance/includes/MigrateActors.php before removal (ba3155214).

Bug: T188180
Change-Id: Ic755526d5f989c4a66b1d37527cda235f61cb437
2023-03-22 14:01:29 +01:00
Matěj Suchánek 8f6a428f02 Replace deprecated database object access methods
Use the very new getPrimaryDatabase and getReplicaDatabase.
We skip FilterLookup and CentralDBManager in this patch.

Change-Id: I22c6f8fa60be90599ee177a4ac4a97e1547f79be
2023-03-08 16:50:56 +01:00
Matěj Suchánek 86ac5bdb40 Clean up database access in non-deployed code
Change-Id: Ibcc41c2dd7f60a806199eaa2c47628a28dadd143
2023-03-03 18:55:08 +01:00
James D. Forrester ebc2e653b0 build: Upgrade mediawiki/mediawiki-codesniffer from 40.0.1 to 41.0.0
Change-Id: I4489dd3935e28a8cdab0d3612ff869854e995c8b
2023-02-26 00:32:51 +00:00
Dreamy Jazz 8e4a1237f1 Hook on privateEvent and logEvent insert hooks like CuChangesInsert
Hook on to CheckUserInsertPrivateEventRow and CheckUserInsertLogEventRow
to override the IP, XFF and User-Agent string when the user is the
abuse filter user for log events.

These two hooks are being added as log entries are being removed from
cu_changes and added into two new tables. Because the columns and their
names are different for these tables, reusing the same hook won't work
for callers that rely on setting values for a specific column name.

Edits and log entries performed by the abuse filter user need to be
marked as being by the software (and not using the IP, XFF and
User-Agent provided in the main request).

These hooks will not be run until the appropriate config is set to
write to the two new tables. Until that point using the one currently
defined hook will work for all actions.

Bug: T324907
Bug: T44345
Depends-On: I7c7754323ade9a8d96273c1742f30b1b5fbe5828
Follow-Up: Idd77545af94f9f9930d9ff38ab6423a72e680df9
Change-Id: Id78417e9d95220946f110afbe1430df5b3bb4f4f
2023-01-08 13:09:52 +00:00
jenkins-bot 595b0a9969 Merge "Ensure IP, XFF and UA are valid for abuse filter user actions in CheckUser" 2023-01-06 20:51:17 +00:00
jenkins-bot 24d797e6cc Merge "Create real integration test for variables" 2022-12-22 02:07:02 +00:00
Matěj Suchánek 3e0d1b0d38 Set old_content_model & new_content_model for past changes
We might consider adding an in-process cache because there
will be a duplicate database lookup for content model and
wikitext of the same revision.

Bug: T230295
Change-Id: I9723f21069e03a49fa7131bd8f79c6e7e442104b
2022-12-18 16:01:45 +00:00
Matěj Suchánek 396d892c60 Use ActionSpecifier to load the IP address
To avoid access to the global request context.

Change-Id: I4d97dbe8b693f1fcd5a4e84f2376752d8e954c18
2022-12-17 22:52:24 +01:00
Matěj Suchánek 52dcd4624f Use ActionSpecifier throughout the code
The motivation is to have a single immutable object providing
information about the action. It can represent the current
action being filtered, but also a past action stored in the
abuse log. It will hopefully help us get rid of passing
User(Identity) and Title/LinkTarget objects around together.

Change-Id: I52fa3a7ea14c98d33607d4260acfed3d3ba60f65
2022-12-16 22:52:03 +00:00
Matěj Suchánek 702d77e3ce Create real integration test for variables
For fixing bugs like T65632, T105325, or T264104, we will need
to update code in more than one place at once. To prevent
regressions, create an integration test which tests the whole
pipeline, from the request submission to variable evaluation.
Edits are simulated using action=edit API call because the hook
AbuseFilter uses is run from EditPage.

To increase confidence in test coverage, remove some annotations
from AbuseFilterConsequencesTest or make them less greedy.
Ideally, it would only test consequences.

This patch includes refactoring of AbuseFilterCreateAccountTestTrait
which now only inserts the user into the database if it really
should be created.
It also restores test coverage of some other classes.

Change-Id: I661f4e0e2bcac4770e499708fca4e4e153f31fed
2022-11-26 18:51:38 +01:00
Reedy 4f4f01f96d EchoNotifierTest: Use namespaced Event class
Re-enables test

Depends-On: Ib57ea2db947285946f31fa9912b37181044df9d3
Change-Id: I082868f4759a5da14235803ebd8a80e794cfe41c
2022-11-12 06:28:33 +00:00
dreamyjazz 627a73ec5e Ensure IP, XFF and UA are valid for abuse filter user actions in CheckUser
Change the IP to 127.0.0.1 (to indicate an internal IP), and blank
the XFF and UA when the performer of an action being logged by
CheckUser is the abuse filter user. Actions performed by the abuse
filter user can only be initated by the software, and as such should
not use the request's IP, XFF and UA. Also test the newly added
code.

Bug: T44345
Depends-On: I28acaaebd2d0067b700da0930e7b7ba924fa5c1c
Change-Id: Idd77545af94f9f9930d9ff38ab6423a72e680df9
2022-11-11 23:19:22 +00:00
Reedy 97e0f30155 EchoNotifierTest: Temporarily skip testNotifyForFilter
Depends-On: Iddb4a5d4057f9c6ed00f754d2e3cd79cd873f212
Change-Id: Id28792658de950b99a8786f881563476def59eba
2022-11-03 00:28:15 +00:00
Daimona Eaytoy 9f78933426 tests: Replace assertNotRegExp with assertDoesNotMatchRegularExpression
The method was renamed in PHPUnit 9.

Done automatically with:
  grep -rl assertNotRegExp tests/ | xargs sed -r -i "s/>assertNotRegExp\(/>assertDoesNotMatchRegularExpression\(/"

Bug: T243600
Change-Id: If0a7775cb96b3c4eb90b6dfe52d8647c12194ccc
2022-10-07 19:06:21 +02:00
Aaron Schulz 67c0f72474 Use MediaWikiIntegrationTestCase::getDb() instead of the "db" member
Bug: T316841
Depends-On: Ia0f3cf49c79affb7189801852ac7e9ec67933a3c
Change-Id: If808cbab429d41e1f2289683533e4a781a4bdf5e
2022-08-31 15:58:00 -07:00
Umherirrender 4fca77068c Clean up line indent with mixed tabs and whitespaces
Change-Id: Icc418130ad34e5f169bfc51bb13b58a7806bd636
2022-07-31 16:34:07 +02:00
jenkins-bot 0925f0753f Merge "Add regression test for abuse log entries" 2022-07-31 12:54:35 +00:00
Matěj Suchánek cb48a6b3ae Add regression test for abuse log entries
We don't have one, and we will need it for
Ib58193927bc8254d36a8de0fd1b5f9fba68a0cb0.

Change-Id: I55c52df8aa0786f5c73a0c957a06a01f9cb86fcd
2022-07-31 14:33:29 +02:00
jenkins-bot 9b62938507 Merge "Add regression test for RunVariableGenerator" 2022-07-31 12:07:15 +00:00
Umherirrender da4bc8643a Use UserIdentity in VariableGenerator::addEditVars
Change-Id: If0a65d7a86de776e6499d43949bfb217f20d9b07
2022-07-29 12:55:52 +02:00
Matěj Suchánek 62e5509772 Add regression test for RunVariableGenerator
Test that null edits do not trigger filters, but sole
content model change does.

Also do some cleanup in AbuseFilterConsequencesTest.
For better isolation, do not access the service
container and do not initialize objects in
the constructor.

Change-Id: I043ecb312226a69d1f485a8382d558ccb899a270
2022-07-16 11:48:42 +02:00
Matěj Suchánek 6b0a8117b8 Try to unbreak tests on sqlite
Change-Id: I65cf163c8698a7457986ef2354c8fa9e30dc47c5
2022-07-16 07:02:48 +00:00
Umherirrender da7683bcbc tests: Improve tests for postgres
Change-Id: I9720b6c7d096ae8415c00eb0ac1ddc461ea0a8dc
2022-07-09 21:40:27 +00:00
jenkins-bot c3c70f7fa0 Merge "FilterProfiler: use WRStats" 2022-07-06 00:05:15 +00:00
Tim Starling cdf2f474e8 FilterProfiler: use WRStats
A new core facility written for this use case.

Bug: T310662
Depends-On: I26b1cdba0a06ad16ad8bb71b455e1b6180924d17
Change-Id: I2b902d034a8c3308c0ba9878b69e873ca8fbda52
2022-07-06 09:35:08 +10:00
Matěj Suchánek e7492a230f Replace unnecessary use of User
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
2022-07-02 23:58:08 +00:00
Matěj Suchánek 799e1db093 Convert remaining permissions checks to use Authority
Change-Id: I5e996cac37bc806db6c3d7ad5c666a606cd79236
2022-07-02 14:49:47 +02:00
DannyS712 139ca18efe Migrate AbuseFilterPermissionManager to authority
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
2022-07-01 06:58:17 +00:00
jenkins-bot af93d83b51 Merge "tests: Improve RCVariableGeneratorTest" 2022-06-30 07:29:48 +00:00
Umherirrender b833d740fd tests: Improve RCVariableGeneratorTest
- use unique ids to find rc entry, to support parallel unit tests and
rdbms where the auto increment value must not increase in time
- Change from Title::newFromText to Title::makeTitle to avoid parsing
the title
- Pass the title to editPage() to avoid reparse of the title
- Use assertSame to compare values

Change-Id: I455b4412a6669475463dee7dea0969ae1cbd8ebb
2022-06-29 22:34:44 +02:00
jenkins-bot 8d4c5d4d33 Merge "Use LinkTarget in ConsequencesExecutor" 2022-06-29 08:52:37 +00:00
jenkins-bot 2314785568 Merge "tests: Avoid Title::newFromText/title parsing" 2022-06-28 21:43:11 +00:00
jenkins-bot 00944567c6 Merge "tests: MWTimestamp::setFakeTime is reset by core" 2022-06-28 21:43:09 +00:00
Matěj Suchánek 4beca85154 Compute user and page age relative to recent change timestamp
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
2022-06-28 20:53:33 +00:00
Umherirrender 32a97e8d15 tests: MWTimestamp::setFakeTime is reset by core
It is in MediaWikiTestCaseTrait since 438b392

Change-Id: Ib89406fdbad0c9fecada50c8f1ee45e27d17c522
2022-06-28 20:48:31 +00:00
Umherirrender 637a88316b tests: Avoid Title::newFromText/title parsing
Using Title::newFromText is parsing the string, which is expensive.
Just use Title::makeTitle when the result is known.
editPage() can take a Title or WikiPage instead of a string, avoid
creation of Title there.
The default ns on editPage() is only needed when giving a string

Change-Id: Ie303b9e6d6b8d6ac80286059f8e86bfc76b779af
2022-06-28 22:46:45 +02:00
Matěj Suchánek b381636974 Extend RCVariableGeneratorTest
Make an edit, retrieve the recent change and test computed variables.

Change-Id: I04beed0b1f7c5adb47e71fd9b03102cb23838e16
2022-06-28 19:50:11 +00:00
Matěj Suchánek 7ae2060b27 Avoid array to object cast in filterToDatabaseRow
Both callers immediately call get_object_vars
to cast it back to array. Avoid this roundtrip.

Change-Id: I6525d76f8a03a4d28c2b50b580c539affe98064f
2022-06-28 18:46:28 +00:00
Umherirrender 20fd8f7b07 Use LinkTarget in ConsequencesExecutor
The Parameters class already only needs a LinkTarget

Change-Id: I4e8e1d7c92f41502a084be3359b97e0d434f08c0
2022-06-28 19:46:50 +02:00
Umherirrender 30fefb75bf Use UserIdentity in ConsequencesExecutor
Change-Id: I281a30610595ed3e984f43aa747eff37abe72939
2022-06-27 22:05:18 +02:00
Daimona Eaytoy f33bc5868c Set the 'timestamp' var in addGenericVars
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
2022-06-26 14:49:40 +02:00
Umherirrender 3d3c45f348 tests: Mock WikiPage in unit test
Bug: T297688
Change-Id: Ic1655141564f02530b1ae6b625a1d3e261a00304
2022-06-24 22:22:24 +02:00
Matěj Suchánek 40564ca635 Remove $info argument from ReversibleConsequence::revert
It was a temporary catch-all variable, but we can replace it
(and probably won't need it).

Change-Id: Ie1a64455c47445050bd83c853b3cafd283d5d020
2022-06-08 11:59:18 +02:00
jenkins-bot 1a6985469b Merge "Inline/simplify smaller pieces of duplicate/complex PHP code" 2022-06-03 20:38:22 +00:00
Thiemo Kreuz bbded6231c Inline/simplify smaller pieces of duplicate/complex PHP code
Change-Id: I59d0f17b77c8c3d47bc532bdefd9d8c0883f180b
2022-06-03 21:04:38 +02:00
jenkins-bot bb94c0914c Merge "Add support for regex string replacements." 2022-05-31 14:54:33 +00:00
Daimona Eaytoy a46db47bd5 Fix validation for ip_in_ranges
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
2022-05-21 15:39:21 +02:00
fossifer b1739a588f Add ip_in_ranges function
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
2022-05-11 12:27:16 +08:00
proc 1d1215bafb
Add support for regex string replacements.
Bug: T285468
Change-Id: I25f8ad1b58cc10f4c6f6ef5ebab99fe58ec71b1e
2022-04-20 18:38:24 +01:00
Daimona Eaytoy 59eb3b70fb Inject dependencies into the authentication provider
- 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
2022-04-09 18:44:25 +02:00
Matěj Suchánek 686d7ea88c Use RestrictionStore instead of deprecated method
Also restructure the unit test a bit.

Change-Id: If5ce26f1bc4efdb29653aed3fc47335dddc1e44c
2022-03-29 16:11:55 +02:00
jenkins-bot bd309bb220 Merge "Clean up test files" 2022-03-25 21:28:10 +00:00
jenkins-bot def507f6d3 Merge "Refactor ConsequencesExecutor to process consequences in more steps" 2022-03-23 09:06:55 +00:00
stang f20699935a Replace (error|warning|success)box in test cases of AbuseFilter
Bug: T304243
Change-Id: Iae2b968fc4c84bf360489ec8ff3491afd476c898
2022-03-20 20:16:31 +00:00
Daimona Eaytoy 8ee9a21750 Clean up test files
Convert a few integration tests to unit tests now that it's possible,
split the AbuseFilterSaveTest file into three different classes.

Change-Id: Ia2c0d7ab878b20a89324336a532abdc44f1e6b74
2022-03-20 17:40:49 +00:00
Daimona Eaytoy 2de5fce177 Refactor ConsequencesExecutor to process consequences in more steps
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
2022-03-19 15:49:36 +00:00
Alexander Vorwerk 4aedfe8d91 Use updated ObjectFactory namespace
Change-Id: I99c5e5664d2401c36a9890f148eba7c25e6e8324
2022-03-09 22:17:07 +00:00
jenkins-bot 894b94bf7d Merge "Add logging when the 'block' action fails" 2022-03-07 09:26:42 +00:00
jenkins-bot dad1fff238 Merge "Overhaul throttle identifiers" 2022-03-06 13:50:43 +00:00
Daimona Eaytoy a0fd0bae01 Overhaul throttle identifiers
- 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
2022-03-06 13:31:06 +00:00
daniel a512ed31a7 Rename private assertion method
assertStatusMessage is being added to MediaWikiTestCaseTrait, rename
a method of the same name in FilterValidatorTest to avoid conflicts.

Change-Id: I642a3b620ab4d8ad620f7a1253fed98d6796883d
NeededBy: Ic01715b9a55444d3df6b5d4097e78cb8ac082b3e
2022-03-05 21:48:18 +00:00
Daimona Eaytoy 496c2ee370 Add logging when the 'block' action fails
Also avoid using User, use Authority instead.

Bug: T303059
Change-Id: I419ab3726d95ef600e2aa14dca5fa14066d245e3
2022-03-05 19:12:53 +00:00
Daimona Eaytoy b5c22f2b77 Improve wording for throttled filter warnings
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
2022-02-22 11:10:19 +00:00
Daimona Eaytoy 167f6cb642 Introduce ActionSpecifier
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
2022-02-18 11:30:56 +00:00
Huji 52827acbab Make rmspecials preserve whitespace
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
2022-02-06 06:07:46 +00:00
Kosta Harlan bc19e738f6 selenium: Run test suites concurrently
Bug: T226869
Change-Id: I0d7435bd6ee9b0893ea387722eaa18a6e120c67a
2022-01-06 15:09:09 +00:00
Alexander Vorwerk ccb85c9a55 Avoid using WikiPage::factory()
WikiPage::factory() is deprecated since 1.36 and should be replaced
with WikiPageFactory::newFromTitle().

Bug: T297688
Change-Id: I85d3566519ab977aad8c517cc48fc8c271e5589a
2021-12-17 09:22:26 +00:00
jenkins-bot 13db4c34e5 Merge "MediaWikiTestCase -> MediaWikiIntegrationTestCase" 2021-10-12 02:16:38 +00:00
Alexander Vorwerk 7cc7cfa806 MediaWikiTestCase -> MediaWikiIntegrationTestCase
MediaWikiTestCase has been renamed to MediaWikiIntegrationTestCase in 1.34.

Bug: T293043
Change-Id: I6e7c5a34ae49d56a8e7b5ac7d06fa9c0283bed5e
2021-10-11 23:32:14 +02:00
jenkins-bot a332b3ff0f Merge "Remove afl_filter entirely" 2021-09-25 01:39:08 +00:00
Daimona Eaytoy e8471a717c Add method to properly check visibility of AbuseLog entries
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
2021-09-25 00:08:33 +00:00
Daimona Eaytoy dae374aec2 Remove afl_filter entirely
As per T220791, the old schema and the flag can be removed in 1.38.

Bug: T220791
Change-Id: Ic6b1c8a22d17a301faf32d2e23778d90c41c39de
2021-09-18 11:06:10 +00:00
Daimona Eaytoy b2dc2c4dd8 Refactor ParserStatus
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
2021-09-17 11:25:54 +00:00
jenkins-bot 5475cae543 Merge "Rename AbuseFilterVariableGeneratorTest" 2021-09-15 17:10:27 +00:00
Matěj Suchánek 3ffbfb63f2 Rename AbuseFilterVariableGeneratorTest
We don't need the AbuseFilter prefix anymore.

Change-Id: Ia54016000895fd22dec5f397ab2d42d20bfd1816
2021-09-15 18:17:36 +02:00
Daimona Eaytoy 7c26c4b8d5 More cleanup for parser-related classes
Change-Id: I6a2bbf519e1d5c6fe2778f69624bd80b9ea1ef86
2021-09-10 12:50:20 +00:00
Daimona Eaytoy a722dfe1a4 Rename ParserFactory -> RuleCheckerFactory
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
2021-09-08 21:59:34 +02:00
Daimona Eaytoy 357ddd498c Clean up / simplify parser-related classes
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
2021-09-08 13:41:52 +02:00
Daimona Eaytoy f8e9ac7e2a Rename AbuseFilterCachingParser -> FilterEvaluator
It's an evaluator, not a parser.

Change-Id: Ib6d33e8423ea72709cf5a33f4397ba33e352ea80
2021-09-08 13:40:47 +02:00
Daimona Eaytoy 6684ea6450 Remove AFPTransitionBase
Also cleanup the mPos hack in the CachingParser.

Change-Id: Ib5693802a3ceb80cb736880ed65e27340abef689
2021-09-06 19:33:48 +00:00
jenkins-bot 199cf1edf8 Merge "Add a static analyzer for the filter language" 2021-09-03 19:51:58 +00:00
Matěj Suchánek 0af21948fc Replace WikiPage::factory in non-test code
Change-Id: I1442ca6603ce5151b98fc88cd84c25af0f34e4f6
2021-09-01 04:55:25 +00:00
Daimona Eaytoy 86257d825c tests: Use DBConnRef, not IDatabase, as retval of getConnectionRef
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
2021-08-31 21:45:10 +02:00
Sorawee Porncharoenwase 320e3d696f Add a static analyzer for the filter language
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
2021-08-31 03:28:24 +02:00
Daimona Eaytoy 704364a5e7 Move parser exceptions to specific namespace and rename them
Create a dedicated "Exception" sub-namespace and remove the "AFP"
prefix, a leftover from the pre-namespace era.

Change-Id: I7e5fded9316d8b7d1628bc1a6ba8b1879ac901e1
2021-08-29 23:38:31 +00:00
jenkins-bot 9b93b0256a Merge "Avoid passing invalid offset to mb_strpos" 2021-08-18 18:45:12 +00:00
Daimona Eaytoy e9795468c4 Switch filterable actions hooks to the new system
Bug: T261067
Bug: T211680
Change-Id: I0e7e4a48b56c3e5fde56f50693fd0cdc19c30dd0
2021-08-16 14:18:56 +00:00
TChin bfa72b9caf Use MovePageFactory
Bug: T252934
Change-Id: I39440ef05d9318f9ab4abd34990887971197a045
2021-08-10 16:31:05 -04:00
Matěj Suchánek ace6f652af AbuseFilterConsequencesTest: Don't call non-static method statically
Change-Id: I0b4ed2f456bf4a52756eb0b98a29994a4a53812c
2021-07-30 01:24:15 +00:00
libraryupgrader 5377ebe819 build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 36.0.0 → 37.0.0

npm:
* postcss: 7.0.35 → 7.0.36
  * https://npmjs.com/advisories/1693 (CVE-2021-23368)

Change-Id: I2b382f3bb236fb44eb24c6a257b13b8fd886541c
2021-07-21 18:51:18 +00:00
DannyS712 745d911d68 Add tests for afl_rev_id being set
Regression tests to make sure T286140 does not
happen again.

In the process, discovered what caused that bug
with afl_rev_id not being set: EditRevUpdater::updateRev()
compares the WikiPage given in the PageSaveComplete hook
to the one given to it by AbuseFilterHooks from
onEditFilterMergedContent, and compares the two using
`===`, meaning that they must refer to the same underlying
object. That bug was caused because AbuseFilterHooks
changed to providing a different object, despite still
referring to the same underlying page.

We should probably change that behavior in EditRevUpdater,
but for now updated AbuseFilterConsequencesTest to pass
the same object around by using RequestContext::setWikiPage()
and providing the WikiPage object to
MediaWikiIntegrationTestCase::editPage().

Bug: T286140
Change-Id: I6562f513c463538af6b59b12a64564b254024613
2021-07-04 08:04:06 +00:00
Daimona Eaytoy 069fa064f5 Avoid passing invalid offset to mb_strpos
Bug: T285978
Change-Id: I3d100fd05f34fe3b01ecbbce5361badc613f9406
2021-07-02 14:07:46 +00:00
DannyS712 47f861b6f6 Pass a user to WikiPage::prepareContentForEdit()
Bug: T285447
Change-Id: I4d277419106c3af5222377a863c80dd866ba188b
2021-06-24 04:01:33 +00:00
jenkins-bot 805ea5b4ff Merge "User mock must return Block instance from getBlock." 2021-06-08 19:14:52 +00:00
jenkins-bot 405e6a7771 Merge "selenium: Update wdio-mediawiki" 2021-06-08 17:35:08 +00:00
daniel 54285fe984 User mock must return Block instance from getBlock.
Change-Id: I569e91dd07b8f89af42344b6d6df87560dcb6bbe
Needed-By: T271494
2021-06-08 17:12:48 +02:00