Last modified: 2011-03-13 18:05:02 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T17476, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 15476 - SpecialVersion upset by anonymous functions in $wgHooks
SpecialVersion upset by anonymous functions in $wgHooks
Status: RESOLVED WONTFIX
Product: MediaWiki
Classification: Unclassified
Special pages (Other open bugs)
1.12.x
All All
: Lowest minor (vote)
: ---
Assigned To: Nobody - You can work on this!
: parser
: 21825 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-09-04 15:11 UTC by Crosbie Fitch
Modified: 2011-03-13 18:05 UTC (History)
4 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Crosbie Fitch 2008-09-04 15:11:29 UTC
ERROR:
DOMDocument::loadXML() [<a href='function.DOMDocument-loadXML'>function.DOMDocument-loadXML</a>]: Premature end of data in tag root line 1 in Entity, line: 182

ANALYSIS:

If a hook is assigned an anonymous function returned by create_function(), e.g. "\0lambda_1" then the initial nul character confuses the parsing of the wikitext created by concatenation of $this->wgHooks() in execute() of SpecialVersion.php

		$wgOut->addWikiText(
			$this->MediaWikiCredits() .
			$this->softwareInformation() .
			$this->extensionCredits() .
			$this->wgHooks()
		);

CAUSE:

For example by:
$wgHooks['MagicWordwgVariableIDs'][]=create_function(...); // assigns "\0lambda_1"

WORKAROUND:

I have a workaround of using trim() to remove the nul chars from the function names:

Line 292 of includes/SpecialVersion.php

	/**
	 * @static
	 *
	 * @param mixed $list Will convert an array to string if given and return
	 *                    the paramater unaltered otherwise
	 * @return mixed
	 */
	function arrayToString( $list ) {
		if( is_object( $list ) ) {
			$class = get_class( $list );
			return "($class)";
		} elseif ( ! is_array( $list ) ) {
************ 	return trim($list);   ********* added trim()
		} else {
			$class = get_class( $list[0] );
			return "($class, {$list[1]})";
		}
	}
Comment 1 Tim Starling 2008-09-06 03:38:06 UTC
create_function() is an ugly hack, and should never have been included in PHP. You shouldn't use it.
Comment 2 Crosbie Fitch 2008-09-06 08:26:29 UTC
The alternative is to create a wrapping system that maps fn+arg to the nul-prefixed names returned by create_function().

Something like this:

$wgHook[..]=array('callCreatedFn',substr(create_function(..),1));

function callCreatedFn($n)
{ $t="\0"+$n;
 return $t();
}

However given the apparent prevalence of its use (see http://www.google.com/search?q=create_function+extension+mediawiki ), it may be appropriate for MW to cater for it.
Comment 3 Daniel Friesen 2008-09-06 14:45:19 UTC
Only old extensions, primarily of which are depreciated or likely don't work with modern code for unrelated reasons make use of create_function.

The only somewhat valid use of create_function I see in that search, is those using $parser->setFunctionHook and using it to set a number of similar but slightly different functions to bypass the fact that they don't know what tag actually called them.

This itself is unrelated to using create_function inside of $wgHooks, and the rationale used for it can't be applied to $wgHooks like it can be to Parser::setFunctionHook. Additionally, that kind of issue has better workarounds. Like making use of a class and using __call so you set things like ClassName::tagHookFoo, ClassName::tagHookBar and redirect them to ClassName::tagHook telling the function whether the foo or bar hook called it.

However even that in itself is just a workaround. If that is the issue, then we should probably consider either passing a parameter to functions so they know what called them, or allowing setFunctionHook to accept passthrough arguments to be given to the other function.


There is no valid reason to use create_function, and there are plenty of reasons against the use of it. No syntax highlighting, can't be optcode cached, inherently slow compared to native code, etc... The whole idea of creating multiple slightly different dynamic functions is screwed up anyways. You're creating multiple functions which are loaded into memory, when a single function that isn't as slow can be used with a little bit of conditions inside of it.
Comment 4 Crosbie Fitch 2008-09-06 16:11:57 UTC
I agree with you Daniel. I would never have thought of using create_function myself, I simply found it used in example code for certain MW extensions which I more or less copied & pasted for my own use. I will rewrite those extensions to avoid create_function.

However:
1) If I adopted code that used create_function() others may too.
2) create_function() is a non-deprecated PHP library function - despite oddly returning a nul prefixed identifier.
3) The MW parser is upset by the nul character when it gets introduced by SpecialVersion in its enumeration of wgHooks.
4) It does take a tadette of detective work to figure out that it is the nul returned by create_function that causes the problem.

I suggest that either:
a) some setup code for wgHooks tests for nul prefixes and triggers an error, or
b) that anything that uses its contents strips/checks for nuls, or
c) the parser treats nul as whitespace, or
d) documentation for wgHooks cautions against use of create_function() and describes the typical errors that result.

Options a-c require code changes. d requires documentation change.

Comment 5 Crosbie Fitch 2008-09-08 14:39:51 UTC
Also occurs in 1.13 (if $wgSpecialVersionShowHooks is true).
Comment 6 Chad H. 2008-09-12 02:46:07 UTC
(In reply to comment #4)
> d) documentation for wgHooks cautions against use of create_function() and
> describes the typical errors that result.
> 
> Options a-c require code changes. d requires documentation change.
> 

Docs updated in r40738.
Comment 7 Crosbie Fitch 2008-09-12 08:04:11 UTC
If documentation is the solution then someone with good authority should also revise this:

http://www.mediawiki.org/wiki/Manual:Variables


Comment 8 Chad H. 2009-07-23 18:34:41 UTC
Marking this as WONTFIX. Docs in source & on MW.org have been updated to reflect that this is not accepted behavior with $wgHooks.
Comment 9 Alexandre Emsenhuber [IAlex] 2009-12-12 14:50:41 UTC
*** Bug 21825 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links