Page MenuHomePhabricator

taint-check fails on array-plus and assumed int|float type
Closed, ResolvedPublic

Description

I have tested mediawiki/phan-taint-check-plugin 3.1.0 against core and it now shows:

float|int passed to foreach instead of array

for following code in PPTemplateFrame_Hash.php

		$args = $this->numberedArgs + $this->namedArgs;
		foreach ( $args as $name => $value ) {
			if ( $first ) {
				$first = false;
			} else {
				$s .= ', ';
			}
			$s .= "\"$name\":\"" .
				str_replace( '"', '\\"', $value->__toString() ) . '"';
		}

It is possible that taint is not assume the corret type here with the array plus?
There is no @var on the class properties, but taint could should be strong about the fact?
Phan without taint does not warn on this foreach.

Event Timeline

It is possible that taint is not assume the corret type here with the array plus?

It is possible, both areas (foreach loops and type inference) were touched between 3.0.4 and 3.1.0. I'm looking.

Not sure if related, but also related to types:

Language.php

Expected an object instance when accessing an instance property, but saw an expression $ts with type string

	private function getHumanTimestampInternal(
		MWTimestamp $ts, MWTimestamp $relativeTo, User $user
	) {
[...]
		if ( $diff->invert || $days > 5
			&& $ts->timestamp->format( 'Y' ) !== $relativeTo->timestamp->format( 'Y' )
		) {

$ts is typehinted and taint lost the type


ResourceLoader.php

Expected an object instance when accessing an instance property, but saw an expression $scripts with type null

		if ( $scripts instanceof XmlJsCode ) {
			if ( $scripts->value === '' ) {  # <!-- issue on this line
				$scripts = null;

It was checked with instanceof


Parser.php

Expected an object instance when accessing an instance property, but saw an expression $this->mPreprocessor with type null

		# Fix cloning
		if ( isset( $this->mPreprocessor ) && $this->mPreprocessor->parser !== $this ) {
			$this->mPreprocessor = null;
		}

Isset should be a null check as well

Change 643990 had a related patch set uploaded (by Daimona Eaytoy; owner: Daimona Eaytoy):
[mediawiki/tools/phan/SecurityCheckPlugin@master] [WIP] PhanTypeMismatchForeach

https://gerrit.wikimedia.org/r/643990

Change 643992 had a related patch set uploaded (by Daimona Eaytoy; owner: Daimona Eaytoy):
[mediawiki/tools/phan/SecurityCheckPlugin@master] Fix bug which made variables lose their type if overridden in branches

https://gerrit.wikimedia.org/r/643992

Not sure if related, but also related to types:

Language.php [...]
ResourceLoader.php [...]
Parser.php [...]

These were caused by the same bug: trying to analyze the if condition after the body. All of those ifs change the type of a variable used in the condition, which resulted in an error. Fixed by avoiding the analysis of the if condition altogether, because redundant and wrong (which should also have the nice side effect of improving performance).

As per link above, this is an upstream issue.

Change 643992 merged by jenkins-bot:
[mediawiki/tools/phan/SecurityCheckPlugin@master] Fix bug which made variables lose their type if overridden in branches

https://gerrit.wikimedia.org/r/643992

Daimona changed the task status from Open to Stalled.EditedDec 11 2020, 9:37 PM

Stalled because the remaining issue should be resolved upstream.

Our part is done. I'm not sure if the upstream issue is going to be fixed: since the addition of numbers is more common than array addition, phan infers number-like types for the operands of + when the types are unknown. Changing that might have unwanted side effects. Since this only caused a single issue in MW core that was promptly suppressed, I believe it's unnecessary to keep this task open.

Change 643990 abandoned by Daimona Eaytoy:

[mediawiki/tools/phan/SecurityCheckPlugin@master] Add tests for PhanTypeMismatchForeach edge case

Reason:

It's an upstream bug, so no need to document it here.

https://gerrit.wikimedia.org/r/643990