/** * Wrapper around unserialize() that converts syntax errors to exceptions. * * @param string $input Serialized string * * @return mixed * * @throws SyntaxError If there was an error unserializing the string */ function unserialize($input) { static $exceptionFactory; $currentHandler = null; if (null === $exceptionFactory) { $exceptionFactory = new SyntaxErrorFactory(); } if (defined('HHVM_VERSION')) { // @codeCoverageIgnoreStart $errorHandler = function ($code, $message, $file, $line) use($exceptionFactory, &$currentHandler, $input) { if ($code === E_NOTICE) { throw $exceptionFactory->create($input, $message); } if ($currentHandler) { return call_user_func_array($currentHandler, func_get_args()); } return false; }; } else { // @codeCoverageIgnoreEnd static $errorHandler; if (!$errorHandler) { $errorHandler = function ($code, $message, $file, $line) use($exceptionFactory, &$currentHandler) { if ($code === E_NOTICE) { $e = new \ErrorException($message, $code, 0, $file, $line); throw $exceptionFactory->createFromErrorException($e); } if ($currentHandler) { return call_user_func_array($currentHandler, func_get_args()); } // @codeCoverageIgnoreStart return false; // @codeCoverageIgnoreEnd }; } } $currentHandler = set_error_handler($errorHandler); try { $result = \unserialize($input); if ($result === false && $input !== 'b:0;') { throw new UnknownException($input, 'Unknown error was encountered'); } } catch (\Exception $e) { throw $e; } finally { // Ensure the error handler is restored. restore_error_handler(); } return $result; }
/** * @dataProvider dataCreate */ public function testCreate($message, $type, $expectedMessage, $expectedOffset = null) { $input = serialize('foobar'); $previous = new \Exception(); $factory = new SyntaxErrorFactory(); $exception = $factory->create($input, $message, $previous); $this->assertInstanceOf('Exception', $exception); $this->assertInstanceOf('Cs278\\SerializationHelpers\\Exception\\Exception', $exception); $this->assertInstanceOf('Cs278\\SerializationHelpers\\Exception\\SyntaxError', $exception); $this->assertInstanceOf("Cs278\\SerializationHelpers\\Exception\\SyntaxError\\{$type}Exception", $exception); $this->assertSame($expectedMessage, $exception->getMessage()); $this->assertSame($previous, $exception->getPrevious()); $this->assertSame($input, $exception->getInput()); if (null !== $expectedOffset) { $this->assertTrue(method_exists($exception, 'getOffset')); $this->assertSame($expectedOffset, $exception->getOffset()); } }