Pastakhov has submitted this change and it was merged.

Change subject: Add params checking in Runtime class (v 5.9)
......................................................................


Add params checking in Runtime class (v 5.9)

* Runtime::VERSION = 11
* remove ErrorHandler

Change-Id: Idba15126bdc212236ea04007fb1e58cf797d9fa8
---
M PhpTags.hooks.php
M extension.json
M includes/Compiler.php
D includes/ErrorHandler.php
M includes/GenericObject.php
M includes/PhpTagsException.php
M includes/Runtime.php
M tests/phpunit/includes/RuntimeTest.php
8 files changed, 868 insertions(+), 120 deletions(-)

Approvals:
  Pastakhov: Verified; Looks good to me, approved



diff --git a/PhpTags.hooks.php b/PhpTags.hooks.php
index 8c5f35a..2092ca1 100644
--- a/PhpTags.hooks.php
+++ b/PhpTags.hooks.php
@@ -107,7 +107,7 @@
                $wgPhpTagsCallsCounter = 0;
 
                define ( 'PHPTAGS_HOOK_RELEASE', 8 );
-               define ( 'PHPTAGS_VERSION', '5.8.1' ); //@todo remove later, it 
only for backward compatibility
+               define ( 'PHPTAGS_VERSION', '5.9' ); //@todo remove later, it 
only for backward compatibility
        }
 
 }
diff --git a/extension.json b/extension.json
index c2caadc..be144cf 100644
--- a/extension.json
+++ b/extension.json
@@ -1,6 +1,6 @@
 {
        "name": "PhpTags",
-       "version": "5.8.1",
+       "version": "5.9",
        "author": "[https://www.mediawiki.org/wiki/User:Pastakhov Pavel 
Astakhov]",
        "url": "https://www.mediawiki.org/wiki/Extension:PhpTags";,
        "descriptionmsg": "phptags-desc",
@@ -21,7 +21,6 @@
                "PhpTags\\iRawOutput": "includes/iRawOutput.php",
                "PhpTags\\outPrint": "includes/outPrint.php",
                "PhpTags\\outStrip": "includes/outStrip.php",
-               "PhpTags\\ErrorHandler": "includes/ErrorHandler.php",
                "PhpTags\\PhpTagsException": "includes/PhpTagsException.php",
                "PhpTags\\HookException": "includes/HookException.php",
                "PhpTags\\Compiler": "includes/Compiler.php",
diff --git a/includes/Compiler.php b/includes/Compiler.php
index d0d46a4..0f4f040 100644
--- a/includes/Compiler.php
+++ b/includes/Compiler.php
@@ -605,7 +605,7 @@
                                                // PHP Parse error:  syntax 
error, unexpected $id
                                                throw new PhpTagsException( 
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), 
$this->tokenLine, $this->place );
                                        }
-                                       if ( $owner === false && 
$variable[Runtime::B_COMMAND] === Runtime::T_VARIABLE ) {
+                                       if ( $owner === false && 
$variable[Runtime::B_COMMAND] === Runtime::T_VARIABLE ) { // $foo = <value> or 
$foo += <value>
                                                $return = array(
                                                        Runtime::B_COMMAND => 
self::$runtimeOperators[$id],
                                                        Runtime::B_PARAM_1 => 
$variable,
@@ -613,6 +613,7 @@
                                                        Runtime::B_RESULT => 
null,
                                                        Runtime::B_TOKEN_LINE 
=> $this->tokenLine,
                                                        Runtime::B_DEBUG => 
$text,
+                                                       Runtime::B_FLAGS => 
($cannotRead === true && $id !== '=') ? Runtime::F_DONT_CHECK_PARAM1 : 0,
                                                );
                                                $this->addValueIntoStack( $val, 
$return, Runtime::B_PARAM_2 );
                                                return $return; // *********** 
EXIT ***********
@@ -966,6 +967,7 @@
                                        Runtime::B_RESULT => null,
                                        Runtime::B_TOKEN_LINE => 
$this->tokenLine,
                                        Runtime::B_DEBUG => $text,
+                                       Runtime::B_FLAGS => 0,
                                );
                                $didit = $this->addValueIntoStack( $value, 
$operator, Runtime::B_PARAM_1, false ); // Add the first value into the stack
 
diff --git a/includes/ErrorHandler.php b/includes/ErrorHandler.php
deleted file mode 100644
index d81cb55..0000000
--- a/includes/ErrorHandler.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-namespace PhpTags;
-
-/**
- * Description of ErrorHandler
- *
- * @author pastakhov
- */
-class ErrorHandler {
-
-       public static function onError( $errno, $errstr, $errfile, $errline, 
$errcontext, $object = false ) {
-               if ( $object === false ) { // @todo wfIsHHVM()
-                       return self::onPhpError( $errno, $errstr, $errfile );
-               }
-               return self::onHhvmError( $errno, $errstr, $errfile );
-       }
-
-       private static function onPhpError( $errno, $errstr, $errfile ) {
-               $backtrace = debug_backtrace();
-               if ( true === isset($backtrace[1]['file']) && strpos( 
$backtrace[1]['file'], 'PhpTags/includes/Runtime.php' ) !== false ) {
-                       if ( strpos( $errstr, 'Division by zero' ) !== false ) {
-                               Runtime::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO, null ) );
-                               return true;
-                       }
-                       $matches = null;
-                       if ( preg_match('/^Object of class ([\\w:\\\\]+) could 
not be converted to (\\w+).*?/', $errstr, $matches) ) {
-                               return self::onRuntimeObjectConvertionError( 
$matches );
-                       }
-               }
-               return false;
-       }
-
-       private static function onRuntimeObjectConvertionError( $matches ) {
-               $object = Runtime::getCurrentOperator();
-               static $previousOperator = false;
-               if ( isset($object[Runtime::B_PARAM_1]) && 
is_a($object[Runtime::B_PARAM_1], $matches[1]) ) {
-                       if ( $previousOperator === $object && 
is_a($object[Runtime::B_PARAM_2], $matches[1]) ) {
-                               $matches[1] = 
$object[Runtime::B_PARAM_2]->getName();
-                       } else {
-                               $matches[1] = 
$object[Runtime::B_PARAM_1]->getName();
-                       }
-               } else {
-                       $matches[1] = $object[Runtime::B_PARAM_2]->getName();
-               }
-               Runtime::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array($matches[1], $matches[2]) ) );
-               $previousOperator = $object;
-               return true;
-       }
-
-       private static function onHhvmError( $errno, $errstr, $errfile ) {
-               $backtrace = debug_backtrace();
-               $matches = null;
-               if ( false !== strpos( $errfile, 'PhpTags/includes/Runtime.php' 
) ) {
-                       if ( strpos( $errstr, 'Division by zero' ) !== false ) {
-                               Runtime::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO, null ) );
-                               return true;
-                       }
-                       $matches = null;
-                       if ( preg_match('/^Object of class ([\\w:\\\\]+) could 
not be converted to (\\w+).*?/', $errstr, $matches) ) {
-                               return self::onRuntimeObjectConvertionError( 
$matches );
-                       }
-               }
-               return false;
-       }
-
-}
diff --git a/includes/GenericObject.php b/includes/GenericObject.php
index 311e625..807d878 100644
--- a/includes/GenericObject.php
+++ b/includes/GenericObject.php
@@ -77,6 +77,19 @@
                return $this->value;
        }
 
+       /**
+        * Returns value for operator (array) and functions var_dump and etc...
+        * @since 5.9
+        * @return array
+        */
+       public function getDumpValue() {
+               return (array)('(' . Runtime::R_DUMP_OBJECT . ' <' . 
$this->getName() . '>)');
+       }
+
+       /**
+        * Returns object's name
+        * @return string
+        */
        public function getName() {
                return $this->objectName;
        }
@@ -100,13 +113,6 @@
 
        public static function getConstantValue( $constantName ) {
                throw new PhpTagsException( 
PhpTagsException::FATAL_CALLCONSTANT_INVALID_HOOK, get_called_class() );
-       }
-
-       /**
-        * @deprecated since you should use get_called_class()
-        */
-       public static function getClassName() {
-               return get_called_class();
        }
 
        protected static function pushExceptionExpectsParameter( $index, 
$expect, $value) {
diff --git a/includes/PhpTagsException.php b/includes/PhpTagsException.php
index d5ae254..e9e549d 100644
--- a/includes/PhpTagsException.php
+++ b/includes/PhpTagsException.php
@@ -194,6 +194,12 @@
                        case self::FATAL_CANNOT_USE_OBJECT_AS_ARRAY:
                                $message = 'Cannot use object as array';
                                break;
+                       case self::FATAL_UNSUPPORTED_OPERAND_TYPES:
+                               $message = 'Unsupported operand types';
+                               break;
+                       case self::FATAL_INTERNAL_ERROR:
+                               $message = 'Unexpected behavior of PhpTags 
(Internal Error):' . $arguments;
+                               break;
                        default:
                                $message = "Undefined error, code 
{$this->code}";
                                $this->code = self::EXCEPTION_FATAL * 1000;
@@ -285,11 +291,14 @@
        const FATAL_UNEXPECTED_OBJECT_TYPE = 4021; // Fatal error: Unexpected 
object type stdClass. in
        const FATAL_WRONG_BREAK_LEVELS = 4022; // PHP Fatal error:  Cannot 
break/continue 4 levels
        const FATAL_CANNOT_USE_OBJECT_AS_ARRAY = 4023; // Cannot use object of 
type %%%%%% as array
+       const FATAL_UNSUPPORTED_OPERAND_TYPES = 4024; // Unsupported operand 
types, example: [1] + 1
 
        const FATAL_DENIED_FOR_NAMESPACE = 4500;
        const FATAL_CALLFUNCTION_INVALID_HOOK = 4501;
        const FATAL_CALLCONSTANT_INVALID_HOOK = 4502;
 
+       const FATAL_INTERNAL_ERROR = 4999; // Unexpected behavior
+
        const EXCEPTION_CATCHABLE_FATAL = 5;
        const FATAL_OBJECT_COULD_NOT_BE_CONVERTED = 5001;  //PHP Catchable 
fatal error:  Object of class stdClass could not be converted to string
 
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 9ba7021..1f9e081 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -11,7 +11,7 @@
  */
 class Runtime {
 
-       const VERSION = 10;
+       const VERSION = 11;
 
        ##### Bytecode array indexes #####
        const B_COMMAND = 0; // Token ID
@@ -29,6 +29,9 @@
        const B_HOOK_TYPE = 12; // describes PhpTags hook type, constant, 
function etc (self::H_...)
        const B_METHOD = 13; // method or function name
        const B_METHOD_KEY = 14; // method or function name in lower case
+       const B_FLAGS = 15;
+
+       const F_DONT_CHECK_PARAM1 = 1;
 
        ##### Hook types #####
        const H_GET_CONSTANT = '_';
@@ -59,6 +62,9 @@
        const S_MEMORY = 5;
        const S_PLACE = 6;
        const S_VARIABLES = 7;
+
+       const R_ARRAY = 'Array';
+       const R_DUMP_OBJECT = 'object';
 
        private static $operators = array(
                self::T_QUOTE => 'doQuote',
@@ -163,7 +169,20 @@
         * @param array $value
         */
        private static function doQuote ( &$value ) {
-               $value[self::B_RESULT] = implode( $value[self::B_PARAM_1] );
+               $implode = array();
+               foreach ( $value[self::B_PARAM_1] as $v ) {
+                       if ( $v === null || is_scalar( $v ) ) {
+                               $implode[] = $v;
+                       } else if ( is_array( $v ) ) {
+                               self::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING ) );
+                               $implode[] = self::R_ARRAY;
+                       } else if ( $v instanceof GenericObject ) {
+                               $implode[] = $v->toString();
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+               $value[self::B_RESULT] = implode( $implode );
        }
 
        /**
@@ -171,7 +190,8 @@
         * @param array $value
         */
        private static function doConcat ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] . 
$value[self::B_PARAM_2];
+               $v = self::checkStringParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2], $value[self::B_FLAGS] );
+               $value[self::B_RESULT] = $v[0] . $v[1];
        }
 
        /**
@@ -179,7 +199,8 @@
         * @param array $value
         */
        private static function doPlus ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] + 
$value[self::B_PARAM_2];
+               $v = self::checkArrayParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] + $v[1];
        }
 
        /**
@@ -187,7 +208,8 @@
         * @param array $value
         */
        private static function doMinus ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] - 
$value[self::B_PARAM_2];
+               $v = self::checkScalarParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] - $v[1];
        }
 
        /**
@@ -195,7 +217,10 @@
         * @param array $value
         */
        private static function doMul ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] * 
$value[self::B_PARAM_2];
+               $v1 = $value[self::B_PARAM_1];
+               $v2 = $value[self::B_PARAM_2];
+               self::checkScalarParams( $v1, $v2 );
+               $value[self::B_RESULT] = $v1 * $v2;
        }
 
        /**
@@ -203,7 +228,15 @@
         * @param array $value
         */
        private static function doDiv ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] / 
$value[self::B_PARAM_2];
+               $v1 = $value[self::B_PARAM_1];
+               $v2 = $value[self::B_PARAM_2];
+               self::checkScalarParams( $v1, $v2 );
+               if ( $v2 == 0 ) {
+                       self::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO ) );
+                       $value[self::B_RESULT] = false;
+               } else {
+                       $value[self::B_RESULT] = $v1 / $v2;
+               }
        }
 
        /**
@@ -211,7 +244,15 @@
         * @param array $value
         */
        private static function doMod ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] % 
$value[self::B_PARAM_2];
+               $v1 = $value[self::B_PARAM_1];
+               $v2 = $value[self::B_PARAM_2];
+               self::checkScalarParams( $v1, $v2 );
+               if ( $v2 == 0 ) {
+                       self::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO ) );
+                       $value[self::B_RESULT] = false;
+               } else {
+                       $value[self::B_RESULT] = $v1 % $v2;
+               }
        }
 
        /**
@@ -219,7 +260,8 @@
         * @param array $value
         */
        private static function doAnd ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] & 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] & $v[1];
        }
 
        /**
@@ -227,7 +269,8 @@
         * @param array $value
         */
        private static function doOr ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] | 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] | $v[1];
        }
 
        /**
@@ -235,7 +278,8 @@
         * @param array $value
         */
        private static function doXor ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] ^ 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] ^ $v[1];
        }
 
        /**
@@ -243,7 +287,8 @@
         * @param array $value
         */
        private static function doShiftLeft ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] << 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] << $v[1];
        }
 
        /**
@@ -251,7 +296,8 @@
         * @param array $value
         */
        private static function doShiftRight ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] >> 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] >> $v[1];
        }
 
        /**
@@ -283,7 +329,8 @@
         * @param array $value
         */
        private static function doIsSmaller ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] < 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] < $v[1];
        }
 
        /**
@@ -291,7 +338,8 @@
         * @param array $value
         */
        private static function doIsGreater ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] > 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] > $v[1];
        }
 
        /**
@@ -299,7 +347,8 @@
         * @param array $value
         */
        private static function doIsSmallerOrEqual ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] <= 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] <= $v[1];
        }
 
        /**
@@ -307,7 +356,8 @@
         * @param array $value
         */
        private static function doIsGreaterOrEqual ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] >= 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] >= $v[1];
        }
 
        /**
@@ -315,7 +365,8 @@
         * @param array $value
         */
        private static function doIsEqual ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] == 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] == $v[1];
        }
 
        /**
@@ -323,7 +374,8 @@
         * @param array $value
         */
        private static function doIsNotEqual ( &$value ) {
-               $value[self::B_RESULT] = $value[self::B_PARAM_1] != 
$value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $value[self::B_PARAM_1], 
$value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $v[0] != $v[1];
        }
 
        /**
@@ -347,10 +399,16 @@
         * @param array $value
         */
        private static function doPrint ( &$value ) {
-               if( $value[self::B_PARAM_1] instanceof GenericObject ) {
-                       self::$stack[0][self::S_RETURN][] = 
$value[self::B_PARAM_1]->toString();
-               } else {
+               $v = $value[self::B_PARAM_1];
+               if ( is_scalar( $v ) || $v === null ) {
                        self::$stack[0][self::S_RETURN][] = 
$value[self::B_PARAM_1];
+               } else if( $v instanceof GenericObject ) {
+                       self::$stack[0][self::S_RETURN][] = 
$value[self::B_PARAM_1]->toString();
+               } else if ( is_array( $v ) ) {
+                       self::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING ) );
+                       self::$stack[0][self::S_RETURN][] = self::R_ARRAY;
+               } else { // Should never happen
+                       throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
                }
        }
 
@@ -359,7 +417,12 @@
         * @param array $value
         */
        private static function doNot ( &$value ) {
-               $value[self::B_RESULT] = ~$value[self::B_PARAM_2];
+               $v = $value[self::B_PARAM_2];
+               if ( $v === null || is_scalar( $v ) ) {
+                       $value[self::B_RESULT] = ~$v;
+               } else {
+                       throw new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES );
+               }
        }
 
        /**
@@ -375,7 +438,9 @@
         * @param array $value
         */
        private static function doIntCast ( &$value ) {
-               $value[self::B_RESULT] = (int)$value[self::B_PARAM_2];
+               $tmp = null;
+               $v = self::checkObjectParams( $value[self::B_PARAM_2], $tmp );
+               $value[self::B_RESULT] = (int)$v[0];
        }
 
        /**
@@ -383,7 +448,9 @@
         * @param array $value
         */
        private static function doDoubleCast ( &$value ) {
-               $value[self::B_RESULT] = (double)$value[self::B_PARAM_2];
+               $tmp = null;
+               $v = self::checkObjectParams( $value[self::B_PARAM_2], $tmp, 
'double' );
+               $value[self::B_RESULT] = (double)$v[0];
        }
 
        /**
@@ -391,7 +458,10 @@
         * @param array $value
         */
        private static function doStringCast ( &$value ) {
-               $value[self::B_RESULT] = (string)$value[self::B_PARAM_2];
+               $tmp = null;
+               $flags = 0;
+               $v = self::checkStringParams( $value[self::B_PARAM_2], $tmp, 
$flags );
+               $value[self::B_RESULT] = (string)$v[0];
        }
 
        /**
@@ -399,7 +469,15 @@
         * @param array $value
         */
        private static function doArrayCast ( &$value ) {
-               $value[self::B_RESULT] = (array)$value[self::B_PARAM_2];
+               $v = $value[self::B_PARAM_2];
+               if ( is_object( $v ) ) {
+                       if ( $v instanceof GenericObject ) {
+                               $v = $v->getDumpValue();
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+               $value[self::B_RESULT] = (array)$v;
        }
 
        /**
@@ -415,7 +493,7 @@
         * @param array $value
         */
        private static function doUnsetCast ( &$value ) {
-               $value[self::B_RESULT] = (unset)$value[self::B_PARAM_2];
+               $value[self::B_RESULT] = null; //(unset)$value[self::B_PARAM_2];
        }
 
        /**
@@ -866,7 +944,8 @@
         */
        private static function doSetConcatVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref .= $value[self::B_PARAM_2];
+               $v = self::checkStringParams( $ref, $value[self::B_PARAM_2], 
$value[self::B_FLAGS] );
+               $value[self::B_RESULT] = $ref = $v[0] . $v[1];
        }
 
        /**
@@ -875,7 +954,8 @@
         */
        private static function doSetPlusVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref += $value[self::B_PARAM_2];
+               $v = self::checkArrayParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] + $v[1];
        }
 
        /**
@@ -884,7 +964,8 @@
         */
        private static function doSetMinusVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref -= $value[self::B_PARAM_2];
+               $v = self::checkScalarParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] - $v[1];
        }
 
        /**
@@ -893,7 +974,8 @@
         */
        private static function doSetMulVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref *= $value[self::B_PARAM_2];
+               $v = self::checkScalarParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] * $v[1];
        }
 
        /**
@@ -902,7 +984,13 @@
         */
        private static function doSetDivVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref /= $value[self::B_PARAM_2];
+               $v = self::checkScalarParams( $ref, $value[self::B_PARAM_2] );
+               if ( $v[1] == 0 ) {
+                       self::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO ) );
+                       $value[self::B_RESULT] = $ref = false;
+               } else {
+                       $value[self::B_RESULT] = $ref = $v[0] / $v[1];
+               }
        }
 
        /**
@@ -911,7 +999,13 @@
         */
        private static function doSetModVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref %= $value[self::B_PARAM_2];
+               $v = self::checkScalarParams( $ref, $value[self::B_PARAM_2] );
+               if ( $v[1] == 0 ) {
+                       self::pushException( new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO ) );
+                       $value[self::B_RESULT] = $ref = false;
+               } else {
+                       $value[self::B_RESULT] = $ref = $v[0] % $v[1];
+               }
        }
 
        /**
@@ -920,7 +1014,8 @@
         */
        private static function doSetAndVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref &= $value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] & $v[1];
        }
 
        /**
@@ -929,7 +1024,8 @@
         */
        private static function doSetOrVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref |= $value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] | $v[1];
        }
 
        /**
@@ -938,7 +1034,8 @@
         */
        private static function doSetXorVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref ^= $value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] ^ $v[1];
        }
 
        /**
@@ -947,7 +1044,8 @@
         */
        private static function doSetShiftLeftVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref <<= $value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] << $v[1];
        }
 
        /**
@@ -956,7 +1054,86 @@
         */
        private static function doSetShiftRightVal ( &$value ) {
                $ref =& self::getVariableRef( $value );
-               $value[self::B_RESULT] = $ref <<= $value[self::B_PARAM_2];
+               $v = self::checkObjectParams( $ref, $value[self::B_PARAM_2] );
+               $value[self::B_RESULT] = $ref = $v[0] >> $v[1];
+       }
+
+       private static function checkStringParams( &$v1, &$v2, &$flags ) {
+               $return = array( $v1, $v2 );
+
+               if ( $v1 !== null && !is_scalar( $v1 ) ) {
+                       if ( is_array( $v1 ) ) {
+                               if ( !($flags & self::F_DONT_CHECK_PARAM1) ) {
+                                       self::pushException( new 
PhpTagsException( PhpTagsException::NOTICE_ARRAY_TO_STRING ) );
+                                       $return[0] = self::R_ARRAY;
+                               }
+                       } else if ( $v1 instanceof GenericObject ) {
+                               $return[0] = $v1->toString();
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+               if ( $v2 !== null && !is_scalar( $v2 ) ) {
+                       if ( is_array( $v2 ) ) {
+                               self::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING ) );
+                               $return[1] = self::R_ARRAY;
+                       } else if ( $v2 instanceof GenericObject ) {
+                               $return[1] = $v2->toString();
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+
+               return $return;
+       }
+
+       private static function checkArrayParams( &$v1, &$v2 ) {
+               if ( !($v1 === null || is_scalar( $v1 )) || !($v2 === null || 
is_scalar( $v2 )) ) {
+                       $return = self::checkObjectParams( $v1, $v2 );
+                       if ( is_array( $v1 ) xor is_array( $v2 ) ) { // [1] + 1 
or 1 + [1]
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES );
+                       }
+               } else {
+                       $return = array( $v1, $v2 );
+               }
+
+               return $return;
+       }
+
+       private static function checkScalarParams( &$v1, &$v2 ) {
+               if ( !($v1 === null || is_scalar( $v1 )) || !($v2 === null || 
is_scalar( $v2 )) ) {
+                       $return = self::checkObjectParams( $v1, $v2 );
+                       if ( is_array( $v1 ) || is_array( $v2 ) ) { // [1] + 1 
or 1 + [1]
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES );
+                       }
+               } else {
+                       $return = array( $v1, $v2 );
+               }
+
+               return $return;
+       }
+
+       private static function checkObjectParams( &$v1, &$v2, $to = 'int' ) {
+               $return = array( $v1, $v2 );
+
+               if ( is_object( $v1 ) ) {
+                       if ( $v1 instanceof GenericObject ) {
+                               self::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array($v1->getName(), $to) ) );
+                               $return[0] = 1;
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+               if ( is_object( $v2 ) ) {
+                       if ( $v2 instanceof GenericObject ) {
+                               self::pushException( new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array($v2->getName(), $to) ) );
+                               $return[1] = 1;
+                       } else {
+                               throw new PhpTagsException( 
PhpTagsException::FATAL_INTERNAL_ERROR, __LINE__ );
+                       }
+               }
+
+               return $return;
        }
 
        private static function & getVariableRef( $value ) {
@@ -1014,7 +1191,6 @@
        }
 
        public static function run( $code, array $args, $scope = '' ) {
-               set_error_handler( '\\PhpTags\\ErrorHandler::onError' );
                try {
                        if( false === isset( self::$variables[$scope] ) ) {
                                self::$variables[$scope] = array();
@@ -1060,17 +1236,15 @@
                        self::$ignoreErrors = false;
                } catch ( \Exception $e ) {
                        Renderer::addRuntimeErrorCategory();
-                       restore_error_handler();
                        self::$ignoreErrors = false;
                        array_shift( self::$stack );
                        throw $e;
                }
-               restore_error_handler();
                array_shift( self::$stack );
                return $stack[self::S_RETURN];
        }
 
-       static function fillList( &$values, &$parametrs, $offset = false ) {
+       private static function fillList( &$values, &$parametrs, $offset = 
false ) {
                $return = array();
 
                for ( $pkey = count( $parametrs ) - 1; $pkey >= 0; --$pkey ) {
diff --git a/tests/phpunit/includes/RuntimeTest.php 
b/tests/phpunit/includes/RuntimeTest.php
index 285381f..e5fb022 100644
--- a/tests/phpunit/includes/RuntimeTest.php
+++ b/tests/phpunit/includes/RuntimeTest.php
@@ -1104,6 +1104,328 @@
                                array('3', '2')
                        );
        }
+       public function testRun_echo_assignment_7() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo = $foo . $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY . 4,
+                                       '4',
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_8() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="4"; $bar=["rrr"]; 
$foo = $foo . $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       4 . Runtime::R_ARRAY,
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_9() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar=["rrr"]; 
$foo = $foo . $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY . Runtime::R_ARRAY,
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_10() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="4"; $bar=["rrr"]; 
$foo .= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       4 . Runtime::R_ARRAY,
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_11() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo .= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY . 'rrr',
+                                       'rrr',
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_12() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar=["rrr"]; 
$foo .= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY . Runtime::R_ARRAY,
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_13() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo=$foo+$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_14() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo+=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_15() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["4"]; 
$foo+=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_16() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar=["4"]; 
$foo+=$bar; echo $foo[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_17() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar=["4"]; 
$foo = $foo + $bar; echo $foo[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_18() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo=$foo-$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_19() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo-=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_20() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo=$foo*$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_21() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo*=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_22() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo=$foo/$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_23() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar="4"; 
$foo/=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_24() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["4"]; 
$foo=$foo%$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_25() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["4"]; 
$foo%=$bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_26() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo and $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_27() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo or $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_28() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo Xor $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_29() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo & $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '0', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_30() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo | $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_31() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo ^ $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_32() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo |= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_33() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo ^= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_34() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo &= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( '0', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_35() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = ($foo >> $bar); echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_36() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["rrr"]; 
$foo = ($foo << $bar); echo $foo,$bar[0];', array('test'), 77777 ),
+                               array( '0', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_37() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo >>= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_38() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["rrr"]; 
$foo <<= $bar; echo $foo,$bar[0];', array('test'), 77777 ),
+                               array( '0', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_39() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = $foo > $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( '1', 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_40() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["rrr"]; 
$foo = $foo < $bar; echo $foo,$bar[0];', array('test'), 77777 ),
+                               array( true, 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_41() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["4"]; $bar="rrr"; 
$foo = $foo == $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array( false, 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_42() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo="rrr"; $bar=["rrr"]; 
$foo = $foo != $bar; echo $foo,$bar[0];', array('test'), 77777 ),
+                               array( true, 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_43() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; $foo = 
~$bar; echo $foo,$bar[0];', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_echo_assignment_44() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; $foo = 
!$bar; echo $foo === false;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+       public function testRun_echo_assignment_45() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(int)$bar; echo $foo === 1;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+       public function testRun_echo_assignment_46() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(double)$bar; echo $foo === (double)1;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+       public function testRun_echo_assignment_47() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(string)$bar; echo $foo;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_echo_assignment_48() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(array)$bar; echo $foo[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_echo_assignment_49() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(bool)$bar; echo $foo === true;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+       public function testRun_echo_assignment_50() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; 
$foo=(unset)$bar; echo $foo === null;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+
+       public function testRun_array_increase_test_1() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; $bar++; echo 
$bar[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_array_increase_test_2() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; ++$bar; echo 
$bar[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_array_increase_test_3() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; --$bar; echo 
$bar[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
+       public function testRun_array_increase_test_4() {
+               $this->assertEquals(
+                               Runtime::runSource( '$bar=["rrr"]; $bar--; echo 
$bar[0];', array('test'), 77777 ),
+                               array( 'rrr' )
+                       );
+       }
 
        public function testRun_echo_ternary_1() {
                $this->assertEquals(
@@ -3242,6 +3564,15 @@
        public function testRun_echo_exception_11() {
                $this->assertEquals( array( false ), Runtime::runSource( 'echo 
@(5/0);', array('Test') ) );
        }
+       public function testRun_echo_exception_12() {
+               $this->assertEquals(
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::WARNING_DIVISION_BY_ZERO, null, 1, 'Test' ),
+                                       false,
+                               ),
+                               Runtime::runSource( 'echo 5%0;', array('Test') )
+                       );
+       }
 
        public function testRun_constant_test() {
                wfDebug( 'PHPTags: this message must be after PHPTags test 
initialization. ' . __METHOD__ );
@@ -3402,4 +3733,297 @@
                $this->assertEquals( $result, array( (string)$exc1, 
(string)$exc2, false ) );
        }
 
+       public function testRun_object_operation_test_1() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar=new 
PhpTagsTest(); $foo = $foo . $bar; echo $foo[0],$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_2() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["rrr"]; $bar=new 
PhpTagsTest(); $foo = $foo + $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_3() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=["rrr"]; $foo += $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_4() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar + $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       6,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_5() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar - $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       4,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_6() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo -= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       -4,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_7() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $foo > $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       false,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_8() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $foo < $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       true,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_9() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar <= $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       false,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_10() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar >= $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       true,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_11() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar == $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       false,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_12() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar != $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       true,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_13() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar === $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       false,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_14() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=5; $foo = $bar !== $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       true,
+                                       5,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_15() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=8; $foo = $bar | $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       9,
+                                       8,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_16() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=8; $foo |= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       9,
+                                       8,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_17() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=8; $foo = $bar >> $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       4,
+                                       8,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_18() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=8; $foo <<= $bar; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       256,
+                                       8,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_19() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=8; $foo = $bar && $foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array(
+                                       true,
+                                       8,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_20() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar= ~$foo; echo $foo,$bar;', array('test'), 77777 ),
+                               array( (string) new PhpTagsException( 
PhpTagsException::FATAL_UNSUPPORTED_OPERAND_TYPES, null, 1, 'test' ) )
+                       );
+       }
+       public function testRun_object_operation_test_21() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar= !$foo; echo $bar === false;', array('test'), 77777 ),
+                               array( true     )
+                       );
+       }
+       public function testRun_object_operation_test_22() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(int)$foo; echo $bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'int'), 1, 
'test' ),
+                                       1,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_23() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(double)$foo; echo $bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_OBJECT_CONVERTED, array('PhpTagsTest', 'double'), 1, 
'test' ),
+                                       1,
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_24() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(string)$foo; echo $bar;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_operation_test_25() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(array)$foo; echo $bar[0];', array('test'), 77777 ),
+                               array( '(object <PhpTagsTest>)' )
+                       );
+       }
+       public function testRun_object_operation_test_26() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(bool)$foo; echo $bar === true;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+       public function testRun_object_operation_test_27() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$bar=(unset)$foo; echo $bar === null;', array('test'), 77777 ),
+                               array( true )
+                       );
+       }
+
+       public function testRun_object_increase_test_1() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$foo++; echo $foo;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_increase_test_2() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
++$foo; echo $foo;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_increase_test_3() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
--$foo; echo $foo;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+       public function testRun_object_increase_test_4() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
$foo--; echo $foo;', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+
+       public function testRun_array_quote_test_1() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=["bar"]; echo 
"$foo";', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::NOTICE_ARRAY_TO_STRING, null, 1, 'test' ),
+                                       Runtime::R_ARRAY,
+                               )
+                       );
+       }
+       public function testRun_object_quote_test_1() {
+               $this->assertEquals(
+                               Runtime::runSource( '$foo=new PhpTagsTest(); 
echo "$foo";', array('test'), 77777 ),
+                               array(
+                                       (string) new PhpTagsException( 
PhpTagsException::FATAL_OBJECT_COULD_NOT_BE_CONVERTED, array('PhpTagsTest', 
'string'), 1, 'test' ),
+                               )
+                       );
+       }
+
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/304200
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Idba15126bdc212236ea04007fb1e58cf797d9fa8
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/PhpTags
Gerrit-Branch: master
Gerrit-Owner: Pastakhov <[email protected]>
Gerrit-Reviewer: Pastakhov <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to