Commit graph

1561 commits

Author SHA1 Message Date
Niklas Laxström
d89704bc4c Improve page display title handling for category pages
One use case of display title is to localise page names with Translate
extension or without. While the page title changes, the subheadings still
say something like "Pages in category Foo/de".

Also converted one raw HTML message to be a parsed message.

First version of this patch caused an issue when previewing
because page title in h1 is not the same as page display title.

This issue is fixed by promoting page display title as it's own member
in OutputPage. Also added getUnprefixedDisplayTitle that attempts to
strip away the namespace prefix to mimic Title::getText() but which
works with display title instead.

Bug: T43720
Bug: T46197
Change-Id: I6097a873297eb57759252fc56ad6d02c44e4c366
2018-09-10 08:29:48 +02:00
Timo Tijhof
2ec27eb038 resourceloader: Refuse to preview content with </script>
Bug: T200506
Change-Id: I4ab5fbb0f5413aad24360169ba635672ce8d9c8e
2018-08-29 23:11:35 +00:00
Timo Tijhof
5d0b5a402e resourceloader: Move logo preload from OutputPage to SkinModule
This was introduced in OutputPage before support for getPreloadLinks()
was added to ResourceLoader. The introduction in ResourceLoader was
actually inspired by this original implementation.

Now that we have it, we should make use of it for this module
as well. Doing so has several benefits:

* Makes the code cleaner by not requiring every skin to implement
  the extra boolean method. Instead, it naturally works. If
  the skin loads the SkinModule, it gets the preload as well.
  If not (such as Minerva, which has a different logo config),
  then it also doesn't get the preload link.
  Naturally, automatic.

* Makes code cleaner by not having static methods, and by not
  having OutputPage call into a Module class.

* Fixes the problem where, if a site's logo is changed, all cached
  HTML is preloading the old logo whilst the stylesheet fetches
  the newer one. Causing both to be downloaded.

* Still preloads the logo well before it can render.

Change-Id: I11b390f2e4f5e7db8b4506ab547839152888005c
2018-08-27 23:05:51 +00:00
Umherirrender
40d3ce8d17 Reduce calls to MediaWikiServices::getInstance()
In some functions MediaWikiServices::getInstance() was called twices or
in loops. Extract the variable to reduce calls.

Change-Id: I2705db11d7a9ea73efb9b5a5c40747ab0b3ea36f
2018-08-18 06:02:39 +02:00
Aryeh Gregor
e68fdb4065 Mass conversion to SpecialPageFactory service
Change-Id: Ia6e1e819ec6cbe8bf75b820109f51d47863e31fc
2018-08-17 12:03:12 -07:00
jenkins-bot
fe25fde55b Merge "Add type hint for ParserOutput" 2018-08-12 07:03:19 +00:00
Aryeh Gregor
90d4f56fe4 Mass conversion of $wgContLang to service
Brought to you by vim macros.

Bug: T200246
Change-Id: I79e919f4553e3bd3eb714073fed7a43051b4fb2a
2018-08-11 22:44:29 -06:00
jenkins-bot
34392825d0 Merge "Comments and code cleanup in OutputPage" 2018-08-09 18:06:05 +00:00
Brian Wolff
146e9c96ea resourceloader: Give module eval the ContentSecurityPolicy nonce
Previously domEval didn't have CSP nonces, causing it to violate
the policy.

Also removes the meta tag scheme, as I could not make it compatible
with how RL storage works using domEval instead of real eval() and
it didn't provide much protection anyways.

Bug: T196923
Change-Id: I3cd2d7cc295c39b498d0bf37915d4ba167fdd48c
2018-08-07 16:54:40 +00:00
Aryeh Gregor
7f0c305c33 Comments and code cleanup in OutputPage
Change-Id: I8c44f30801792e8b84ab3d556cb5b1b5feb9baf3
2018-08-03 10:52:34 +03:00
jenkins-bot
d9327f9a57 Merge "Improve OutputPage test coverage more" 2018-08-02 03:03:22 +00:00
Aryeh Gregor
5daf4022a2 Improve OutputPage test coverage more
Improved locally from 26.81% to 37.18%.

Depends-On: Ib564624c644ee6620ac06872f5684831acaaaadb
Change-Id: Icdc0288c04b8c4ba841f9fbb3e05a0cdc8a20fa5
2018-08-01 16:08:46 +03:00
Aryeh Gregor
a5853433da Remove long-dead OutputPage methods set/getPageTitleActionText()
They were accidentally made non-functional in April 2009 by commit
e4d21170.  Subsequent commits 2d045fa1, 9e230f30, e275ea28, ae45908c
removed all callers by October 2011.  Needless to say, I found no
callers in core or extensions.

It seems we have the functionality in some other way, probably just by
directly calling setHTMLTitle(), so there's no need to revive this
feature.

Bug: T200643
Change-Id: Ifa2537b97cf19e7e91ee33d4ea4c131f7a38ee89
2018-08-01 10:14:42 +00:00
jenkins-bot
b1289408df Merge "Improve test coverage for OutputPage" 2018-07-30 12:48:49 +00:00
Aryeh Gregor
243e0f5d6c Improve test coverage for OutputPage
Raises coverage locally from 16.10% to 26.81%.

Change-Id: Ib564624c644ee6620ac06872f5684831acaaaadb
Depends-On: I79c4e37092958c63a693194b27a9eafae70cb2f8
2018-07-30 05:08:54 -07:00
Fomafix
6a022c8d20 Add type hint for ParserOutput
EditPage::getPreviewLimitReport is called by EditPage::showEditForm
with $output = null. Specify this in the @param tag and allow this by a
default value.

Change-Id: Iec8905aab736a1f254a57853c7cab935d008653e
2018-07-30 09:23:59 +02:00
jenkins-bot
e8efad4669 Merge "Use array_merge() for OutputPage::$mLanguageLinks, not +" 2018-07-30 03:14:34 +00:00
Aryeh Gregor
8a1bc59d11 Use array_merge() for OutputPage::$mLanguageLinks, not +
Based on documentation together with inspection of some callers, the
intent seems to be that this is an indexed array, not associative.  +
will therefore do totally the wrong thing, ignoring any new values that
have the same key as an existing item (e.g., '0' or '1').  Even if it
was an associative array, + keeps the values on the left-hand side,
which means you normally want to do $foo = $bar + $foo instead of $foo
+= $bar if you want to overwrite old values with the new ones.

Before this change, calling addLanguageLinks() or
addParserOutputMetadata() would generally not add all of the links it
was supposed to if there were already links defined.  (It could still
work if the arrays' keys didn't conflict for some reason, e.g.,
something passed an associative array or an indexed array with a hole.)
I don't know if anything actually hits this bug, because it's likely
that callers usually add all their links at once.  I find no uses of
addLanguageLinks() at all.

I found this bug while working on adding more tests for OutputPage, and
the tests for this change will be submitted later in
Icdc0288c04b8c4ba841f9fbb3e05a0cdc8a20fa5.

Change-Id: I53f6e7ea94417b0034371e56e733e8c86af21658
2018-07-29 14:21:10 +03:00
Aryeh Gregor
62eea350d7 Remove two unused OutputPage methods
addMetadataLink and getMetadataAttribute were added in 2004 (22f8c4ce)
for functionality that was moved to extensions in 2011 (27c3b22b).
Those extensions, CreateCommonsRdf and DublinCoreRdf, now use
addHeadItem() directly.  There are no other callers in core or
extensions.

Change-Id: I4bc21fdaefc8f56969a2950eb53b340bf4aac399
2018-07-26 14:02:20 +03:00
Aryeh Gregor
dcb721dca4 Make OutputPage::mPagetitle private
Code search revealed only one outside access, which I've submitted a patch for.

Depends-On: I001deecad241b091070483d882088d2d6361ed5a
Change-Id: I0f7e565f4eacc1074c619772b2d11a47a05e3584
2018-07-24 16:40:37 +03:00
Jack Phoenix
0ed71cb0e0 New 'OutputPageAfterGetHeadLinksArray' hook, allowing extensions to modify the return value of OutputPage#getHeadLinksArray
Code from wikiHow codebase, where this hook is used by the following extensions:
* AlternateDomain -- used to remove certain links altogether and change the contents of other elements (e.g. <meta description="..." />)
* hooks (PageHooks) -- used to hide certain links for anons on noindexed pages to avoid leaking article info to Googlebot
* QADomain -- used to remove certain elements and correct <meta keywords="..." /> tags not to mention "wikiHow" if that string is present
* search (LSearch) -- used to remove canonical URL on Special:LSearch for SEO

Change-Id: I4a9ceb343bb5c0b4eb79e4589d36c3790938f8a9
2018-07-15 02:08:16 +03:00
Brian Wolff
cb57179a01 Deprecate specialized file errors in OutputPage and fix escaping
OutputPage has a number of specialized error reporting methods
related to file handling. With exception of showFileDeleteError,
they are all unused. In my opinion such specialized error handling
does not belong in OutputPage, but in whatever class is generating
the error.

Futhermore, these functions do not appropriately escape their
arguments or their i18n messages. I replaced the one usage
in SpecialUpload with an equivalent that does escape properly.
This is not exploitable as the attacker is not in control of
the temporary file name, but it is very bad practice.

This deprecates the following methods:
* OutputPage::showFileDeleteError()
* OutputPage::showFileNotFoundError()
* OutputPage::showFileRenameError()
* OutputPage::showFileCopyError()
* OutputPage::showUnexpectedValueError()

[Discovered with the help of an experimental phan plugin]

Change-Id: I9e7aaa59ded66f32c78cfdfed1e59e073ffd5051
2018-07-11 18:57:24 +00:00
Brian Wolff
53a18d1294 CSP: Allow an option of disabling nonces
The current rollout plan calls for initial rollout to only
disallow external JS, and leave removing unsafe inline stuff
to a later date. Thus this adds a useNonces option to the CSP
config to allow that.

Renamed ContentSecurityPolicy::isEnabled() to isNonceRequired
for clarity. The old name has never been in a released version
of MediaWiki, so is removed immediately.

Change-Id: I756d8e97b77c6f97dbbf040a20c8750fecb157c5
2018-07-10 00:12:32 +00:00
Umherirrender
130ec2523d Fix PhanTypeMismatchDeclaredParam
Auto fix MediaWiki.Commenting.FunctionComment.DefaultNullTypeParam sniff

Change-Id: I865323fd0295aabd06f3e3c75e0e5043fb31069e
2018-07-07 00:34:30 +00:00
Umherirrender
ae2f5d6232 Add missing use statements
Swap some ResultWrapper/Database to interface IResultWrapper/IDatabase

Change-Id: I312cb3cca5742f72efdb0965ba35362f2eb1129d
2018-06-27 20:49:23 +02:00
jenkins-bot
84fa176c9c Merge "Avoid deprecated LinkCache::singleton()" 2018-06-14 23:48:54 +00:00
Fomafix
0f1858321c Use PHP 7 '??' operator instead of if-then-else
Change-Id: I790b86e2e9e3e41386144637659516a4bfca1cfe
2018-06-12 23:14:18 +02:00
Fomafix
e1630b6a53 PHP: Use short ternary operator (?:) where possible
Change-Id: Idcc7e4fcdd4d8302ceda44bf6d294fa8c2219381
2018-06-11 11:26:35 +02:00
Kunal Mehta
c4e5a9dd97 Avoid deprecated LinkCache::singleton()
Change-Id: Ie0e5c4ef0fe6ec896378bb2433af0898655dd907
2018-06-10 23:55:11 -07:00
Max Semenik
9bab7de5f8 Clean up CSPRNG support for PHP7
Replace it all with random_bytes(), leave
only MWCryptRand::generateHex() as a convenience helper.

Change-Id: Ic30376a90e66d8f00dab86e7e6466fb3a750b87d
2018-06-10 00:52:04 +00:00
Max Semenik
6e956d55aa Replace call_user_func_array(), part 2
Uses new PHP 5.6 syntax like ...parameter unpacking and
calling anything looking like a callback to make the code more readable.
There are much more occurrences but this commit is intentionally limited
to an easily reviewable size.

In one occurrence, a simple conditional instead of trickery was much more readable.

This patch finishes all the easy stuf in the core, the remainder is either unobvious
or would result in smaller readability gains. It will be carefully dealt with in
further commits.

Change-Id: I79a16c48bfb98b75e5b99f2f6f4fa07b3ae02c5b
2018-06-07 20:19:26 -07:00
Bartosz Dziewoński
485f66f174 Use PHP 7 '??' operator instead of '?:' with 'isset()' where convenient
Find: /isset\(\s*([^()]+?)\s*\)\s*\?\s*\1\s*:\s*/
Replace with: '\1 ?? '

(Everywhere except includes/PHPVersionCheck.php)
(Then, manually fix some line length and indentation issues)

Then manually reviewed the replacements for cases where confusing
operator precedence would result in incorrect results
(fixing those in I478db046a1cc162c6767003ce45c9b56270f3372).

Change-Id: I33b421c8cb11cdd4ce896488c9ff5313f03a38cf
2018-05-30 18:06:13 -07:00
Bartosz Dziewoński
b191e5e860 Use PHP 7 '<=>' operator in 'sort()' callbacks
`$a <=> $b` returns `-1` if `$a` is lesser, `1` if `$b` is lesser,
and `0` if they are equal, which are exactly the values 'sort()'
callbacks are supposed to return.

It also enables the neat idiom `$a[x] <=> $b[x] ?: $a[y] <=> $b[y]`
to sort arrays of objects first by 'x', and by 'y' if they are equal.

* Replace a common pattern like `return $a < $b ? -1 : 1` with the
  new operator (and similar patterns with the variables, the numbers
  or the comparison inverted). Some of the uses were previously not
  correctly handling the variables being equal; this is now
  automatically fixed.
* Also replace `return $a - $b`, which is equivalent to `return
  $a <=> $b` if both variables are integers but less intuitive.
* (Do not replace `return strcmp( $a, $b )`. It is also equivalent
  when both variables are strings, but if any of the variables is not,
  'strcmp()' converts it to a string before comparison, which could
  give different results than '<=>', so changing this would require
  careful review and isn't worth it.)
* Also replace `return $a > $b`, which presumably sort of works most
  of the time (returns `1` if `$b` is lesser, and `0` if they are
  equal or `$a` is lesser) but is erroneous.

Change-Id: I19a3d2fc8fcdb208c10330bd7a42c4e05d7f5cf3
2018-05-30 18:05:20 -07:00
jenkins-bot
0a6eedc440 Merge "OutputPage: Remove 'X-UA-Compatible' header (was for IE8-10 JS compat)" 2018-05-30 18:08:24 +00:00
Elliott Eggleston
e7d1424792 OutputPage: Remove 'X-UA-Compatible' header (was for IE8-10 JS compat)
Save 26 bytes each request.

We're not sending JS to those browsers any more, they're dying out, and
apparently just the `<!DOCTYPE html>` is enough to trigger Edge mode.

https://stackoverflow.com/questions/26346917/why-use-x-ua-compatible-ie-edge-anymore

Bug: T27378
Change-Id: I5418d4b043a8c8669886c39a93732e4a7d50337e
2018-05-28 00:04:05 +00:00
Timo Tijhof
5d000f3b41 OutputPage: Remove appending of wgStyleVersion to legacy resources
For addScriptFile(), just remove the appending of wgStyleVersion.
Going forward, anyone still using this, should simply append a query
parameter themselves in a way that is specific to that one url
(instead of relying on a generic global variable). Alternatively, one
could use OutputPage::transformResourcePath if the file is in /w/.

For addStyles(), also remove the appending of wgStyleVersion. Since this
method takes paths relative to /w/skins, we can easily update this to
automatically use transformResourcePath(), so that file-hash based query
parameters are automatically added.

Test Plan:
* Add calls to top of OutputPage::output():
  `$this->addStyle( 'Vector/README.md' );`
  `$this->addScriptFile( "{$GLOBALS['wgScriptPath']}/composer.json" );`
* Before, they are both inserted as `<link>` (head) and `<script>` (body)
  with a query parameter based on wgStyleVersion.
* After, the `<script>` (end of body) has no query.
  After, the stylesheet (head) has a SHA1 content hash as query.

Bug: T181318
Change-Id: Ie5ab5066ef7d07279086bde838d7305e9e4eabaf
2018-05-23 20:00:28 +00:00
Timo Tijhof
7477558980 OutputPage: Remove support for non-existent /w/skins/common directory
Test Plan:
* Add calls `$this->addScriptFile( 'example.js' )` and
  `$this->addScriptFile( '/example.js' )` to top of OutputPage::output().
* Without this change, two `<script>` are added.
* With this change, only for the latter a script is added,
  and the former triggers a deprecation warning.

Bug: T71277
Bug: T181318
Change-Id: I0576ef09fafa4ba34d52d75f4211fcfa28f4f3b0
2018-05-22 11:07:42 +00:00
Timo Tijhof
ee8a5e488e resourceloader: Apply safemode to startup module registry
This effectively applies safemode to the mw.loader client,
without the client itself needing specific knowledge of safemode.

Test Plan:
* Unchanged: When viewing a page in safemode, the 'user' and
  'site' modules are still not queued by OutputPage.
* New: mw.loader.getState('site'), previously would yield
  'registered', but will now yield null.
* New: mw.loader.load('site'), previously loaded the module,
  it now logs a dependency warning for unknown module, like for
  any other unknown module.
* New: mw.loader.using('site'), previously resolved, it is now
  rejected.

Bug: T185303
Change-Id: I672e3891c8e1b3c2d13655fa134d0f1d031b8247
2018-05-19 22:14:33 +02:00
Timo Tijhof
0980f94e13 resourceloader: Refactor CSP $nonce passing
Follows-up 70941efd35 which broke various public
signatures of the ClientHtml class that I'd prefer to handle
differently.

This commit mainly restores support for all previously public
signatures, and either removes the need for a parameter, or moves
it to the end of the original signature (as optional param).

* ClientHtml::getHeadHtml: Remove the positional/required parameter
  that was added. Restoring the method to being a stateless computer
  that requires no parameters. Pass the option via construct instead.

* ClientHtml::makeLoad:
  - Make $nonce optional.
  - Restore $extraQuery as optional.

* ResourceLoader::makeInlineScript: Document $nonce as optional
  (matching the implementation).

Change-Id: Iaf33f2a060048e6606fba8d875b6d2953b21ef45
2018-05-17 22:28:23 -07:00
Brian Wolff
70941efd35 Initial support for Content Security Policy, disabled by default
The primary goal here is a defense in depth measure to
stop an attacker who found a bug in the parser allowing
them to insert malicious attributes.

This wouldn't stop someone who could insert a full
script tag (since at current it can't distinguish between
malicious and legit user js). It also would not prevent
DOM-based or reflected XSS for anons, as the nonce value
is guessable for anons when receiving a response cached
by varnish. However, the limited protection of just stopping
stored XSS where the attacker only has control of attributes,
is still a big win in my opinion. (But it wouldn't prevent
someone who has that type of xss from abusing things like
data-ooui attribute).

This will likely break many gadgets. Its expected that any
sort of rollout on Wikimedia will be done very slowly, with
lots of testing and the report-only option to begin with.

This is behind feature flags that are off by default, so
merging this patch should not cause any change in default
behaviour.

This may break some extensions (The most obvious one
is charinsert (See fe648d41005), but will probably need
some testing in report-only mode to see if anything else breaks)

This uses the unsafe-eval option of CSP, in order to
support RL's local storage thingy. For better security,
we may want to remove some of the sillier uses of eval
(e.g. jquery.ui.datepicker.js).

For more info, see spec: https://www.w3.org/TR/CSP2/
Additionally see:
https://www.mediawiki.org/wiki/Requests_for_comment/Content-Security-Policy

Bug: T135963
Change-Id: I80f6f469ba4c0b608385483457df96ccb7429ae5
2018-05-13 21:01:11 -07:00
Timo Tijhof
a63088d496 resourceloader: Deprecate OutputPage::addModuleScripts()
And the counter-part in ParserOutput as well.

This follows-up on 80e5b160e0, which removed the last use of this
method. It also deprecated ResourceLoaderClientHtml::setModuleScripts()
but that isn't usually used directly. The public interfaces are
mainly in OutputPage/ParserOutput, which are now deprecated as well.

Bug: T188689
Change-Id: I90baafdfc089ac03c4c3abc12065c0b60d43994e
2018-05-07 14:26:56 +01:00
jdlrobson
a01d8be82c Skins: getDefaultStyles can now define render blocking CSS
This optimisation attempts to minimise loading the styles in places
they are not needed.

The logic is kept inside Skin::getDefaultModules to avoid fragmentation
of where modules get defined.

Update ApiParse to avoid repetition of code.

Bug: T42792
Bug: T42812
Change-Id: I59f02a7bab3baa9d43f6bc2ef1f549d9d31d8456
2018-04-26 13:00:19 -07:00
Brad Jorsch
3f1142045f Generalize ResourceLoader 'excludepage' functionality
There has long been a hack for previewing edits to user JS/CSS, where
OutputPage would pass an 'excludepage' parameter to
ResourceLoaderUserModule to tell it not to load one particular page and
would instead embed that page statically. That's nice, but there are
other places where we could use the same thing.

This patch generalizes it:
* DerivativeResourceLoaderContext may now contain a callback for mapping
  titles to replacement Content objects.
* ResourceLoaderWikiModule::getContent() uses the overrides, and
  requests embedding when they're used. All subclasses in Gerrit should
  pick it up automatically.
* OutputPage gains methods for callers to add to the override mapping,
  which it passes on to RL. It loses a bunch of the special casing it
  had for the 'user' and 'user.styles' modules.
* EditPage sets the overrides on OutputPage when doing the preview, as
  does ApiParse for prop=headhtml. TemplateSandbox does too in I83fa0856.
* OutputPage::userCanPreview() gets less specific to editing user CSS
  and JS, since RL now handles the embedding based on the actual
  modules' dependencies and EditPage only requests it on preview.

ApiParse also gets a new hook to support TemplateSandbox's API
integration (used in I83fa0856).

Bug: T112474
Change-Id: Ib9d2ce42931c1de8372e231314a1f672d7e2ac0e
2018-04-25 00:37:08 +00:00
Timo Tijhof
8f8b0de932 OutputPage: Factor out CdnCacheEpoch logic and cover with tests
Bug: T178629
Change-Id: Ife7dd79677c2b5353317e06ac7ed521edd6193cc
2018-04-20 16:01:35 +01:00
James D. Forrester
225b462a50 Drop deprecated EnableAPI and EnableWriteAPI settings
The siteinfo API response's 'writeapi' value is now hard-set to true,
as are the ResourceLoader variables wgEnableAPI and wgEnableWriteAPI,
to be deprecated later.

Bug: T115414
Change-Id: I54ff9428b247ba203d67aba079149393f323d5a9
2018-04-18 00:30:34 +00:00
Timo Tijhof
cfdc440d40 resourceloader: Replace ClientHtml 'target' param with 'options' array
In preparation for passing down 'safemode' from OutputPage.

Only used in one place in Wikimedia Git: OutputPage::getRlClient().

Bug: T185303
Change-Id: If01eca96986ff8d7dcdaab6910bf183ba7c7311f
2018-03-27 18:17:43 -07:00
James D. Forrester
6d4e15476c Title: Refactor JS/CSS page handling to be more sane
Change-Id: Ia7837dc614dcc8896a7d4b6d663dc45b6bd4f7ee
2018-02-16 17:35:12 +00:00
jenkins-bot
fc0b2a62cc Merge "Hard-deprecate ParserOutput stateful transform methods" 2018-02-15 02:14:07 +00:00
Umherirrender
09cfb1269a resourceloader: Remove ResourceLoaderModule::getPosition
@deprecated since 1.29

Bug: T184257
Change-Id: I1a59a1f0a5fbedfea9f0b28bee8c298710557a8d
2018-02-14 23:50:09 +00:00
Brad Jorsch
2791fb0861 Hard-deprecate ParserOutput stateful transform methods
This also removes all the in-core calls that had been kept for the
benefit of extensions, and causes them to not have any effect since
anything that had been calling them was already either a no-op or will
probably be broken now that nothing in core is setting or checking the
flags.

Change-Id: Id22c1a5a6d6a249debb14063ae3f8838d105b634
2018-02-13 12:28:36 -05:00