Allow if without else

Bug: T230727
Depends-On: I8e7f7710b8cb37ada8531b631456a3ce7b27ee45
Change-Id: I3b85087677607573f4fa68681735dc35348dcd87
This commit is contained in:
Daimona Eaytoy 2019-08-20 18:19:31 +02:00 committed by Krinkle
parent 963221ad6d
commit af7744781f
6 changed files with 28 additions and 37 deletions

View file

@ -23,8 +23,8 @@ class AFPTreeNode {
const ARRAY_APPEND = 'ARRAY_APPEND';
// CONDITIONAL represents both a ternary operator and an if-then-else-end
// construct. The format is (condition, evaluated-if-true,
// evaluated-in-false), all tree nodes.
// construct. The format is (condition, evaluated-if-true, evaluated-in-false).
// The first two are tree nodes, the last one can be a node, or null if there's no else.
const CONDITIONAL = 'CONDITIONAL';
// LOGIC is a logic operator accepted by AFPData::boolOp. The format is

View file

@ -236,19 +236,12 @@ class AFPTreeParser {
$valueIfTrue = $this->doLevelConditions();
if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) ) {
throw new AFPUserVisibleException( 'expectednotfound',
$this->mPos,
[
'else',
$this->mCur->type,
$this->mCur->value
]
);
if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) {
$this->move();
$valueIfFalse = $this->doLevelConditions();
} else {
$valueIfFalse = null;
}
$this->move();
$valueIfFalse = $this->doLevelConditions();
if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'end' ) ) {
throw new AFPUserVisibleException( 'expectednotfound',

View file

@ -240,11 +240,16 @@ class AbuseFilterCachingParser extends AbuseFilterParser {
list( $condition, $valueIfTrue, $valueIfFalse ) = $node->children;
$condition = $this->evalNode( $condition );
if ( $condition->toBool() ) {
$this->discardWithHoisting( $valueIfFalse );
if ( $valueIfFalse !== null ) {
$this->discardWithHoisting( $valueIfFalse );
}
return $this->evalNode( $valueIfTrue );
} else {
$this->discardWithHoisting( $valueIfTrue );
return $this->evalNode( $valueIfFalse );
return $valueIfFalse !== null
? $this->evalNode( $valueIfFalse )
// We assume null as default if the else is missing
: new AFPData( AFPData::DNULL );
}
case AFPTreeNode::ASSIGNMENT:

View file

@ -508,7 +508,8 @@ class AbuseFilterParser {
$this->move();
$r1 = new AFPData( AFPData::DEMPTY );
$r2 = new AFPData( AFPData::DEMPTY );
// DNULL is assumed as default in case of a missing else
$r2 = new AFPData( AFPData::DNULL );
$isTrue = $result->toBool();
@ -520,24 +521,16 @@ class AbuseFilterParser {
$this->mShortCircuit = $scOrig;
}
if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) ) {
throw new AFPUserVisibleException( 'expectednotfound',
$this->mCur->pos,
[
'else',
$this->mCur->type,
$this->mCur->value
]
);
}
$this->move();
if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) {
$this->move();
if ( $isTrue ) {
$scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true );
}
$this->doLevelConditions( $r2 );
if ( $isTrue ) {
$this->mShortCircuit = $scOrig;
if ( $isTrue ) {
$scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true );
}
$this->doLevelConditions( $r2 );
if ( $isTrue ) {
$this->mShortCircuit = $scOrig;
}
}
if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'end' ) ) {

View file

@ -57,8 +57,6 @@ false & (
var9 := 'foo';
if ( 1=== 1 ) then
( false & ( var9 := 'foobar' ) )
else
( 0 )
end;
var1 === 1 &

View file

@ -1,2 +1,4 @@
(if 1 then 2 else 3 end) === 2 &
(if false then 2 else 3 end) === 3
(if false then 2 else 3 end) === 3 &
(if true then 3 end) === 3 &
(if false then 3 end) === null