Bläddra i källkod

Merge branch '1.x'

Jordi Boggiano 7 år sedan
förälder
incheckning
873ac681a6

+ 20 - 0
CHANGELOG.md

@@ -1,3 +1,23 @@
+### 1.24.0 (2018-06-xx)
+
+  * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler
+  * Added InsightOpsHandler to migrate users of the LogEntriesHandler
+  * Added protection to NormalizerHandler against circular and very deep structures, it now stops normalizing at a depth of 9
+  * Added capture of stack traces to ErrorHandler when logging PHP errors
+  * Added forwarding of context info to FluentdFormatter
+  * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example
+  * Added ability to extend/override BrowserConsoleHandler
+  * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility
+  * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility
+  * Dropped official support for HHVM in test builds
+  * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases
+  * Fixed normalization of objects in Slack handlers
+  * Fixed support for PHP7's Throwable in NewRelicHandler
+  * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory
+  * Fixed table row styling issues in HtmlFormatter
+  * Fixed RavenHandler dropping the message when logging exception
+  * Fixed WhatFailureGroupHandler skipping processors when using handleBatch
+
 ### 1.23.0 (2017-06-19)
 
   * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument

+ 12 - 1
src/Monolog/Formatter/NormalizerFormatter.php

@@ -187,9 +187,20 @@ class NormalizerFormatter implements FormatterInterface
             if (isset($frame['file'])) {
                 $data['trace'][] = $frame['file'].':'.$frame['line'];
             } elseif (isset($frame['function']) && $frame['function'] === '{closure}') {
-                // We should again normalize the frames, because it might contain invalid items
+                // Simplify closures handling
                 $data['trace'][] = $frame['function'];
             } else {
+                if (isset($frame['args'])) {
+                    // Make sure that objects present as arguments are not serialized nicely but rather only
+                    // as a class name to avoid any unexpected leak of sensitive information
+                    $frame['args'] = array_map(function ($arg) {
+                        if (is_object($arg) && !$arg instanceof \DateTimeInterface) {
+                            return sprintf("[object] (%s)", get_class($arg));
+                        }
+
+                        return $arg;
+                    }, $frame['args']);
+                }
                 // We should again normalize the frames, because it might contain invalid items
                 $data['trace'][] = $this->toJson($this->normalize($frame, $depth + 1), true);
             }

+ 4 - 0
src/Monolog/Handler/TestHandler.php

@@ -84,6 +84,10 @@ class TestHandler extends AbstractProcessingHandler
         return isset($this->recordsByLevel[$level]);
     }
 
+    /**
+     * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records
+     * @param int          $level  Logger::LEVEL constant value
+     */
     public function hasRecord($record, $level)
     {
         if (is_string($record)) {

+ 33 - 14
tests/Monolog/Formatter/NormalizerFormatterTest.php

@@ -393,10 +393,6 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
     // and no file or line are included in the trace because it's treated as internal function
     public function testExceptionTraceWithArgs()
     {
-        if (defined('HHVM_VERSION')) {
-            $this->markTestSkipped('Not supported in HHVM since it detects errors differently');
-        }
-
         try {
             // This will contain $resource and $wrappedResource as arguments in the trace item
             $resource = fopen('php://memory', 'rw+');
@@ -416,16 +412,8 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
         $record = ['context' => ['exception' => $e]];
         $result = $formatter->format($record);
 
-        $this->assertRegExp(
-            '%\[resource\(stream\)\]%',
-            $result['context']['exception']['trace'][0]
-        );
-
-        $pattern = '%\[\{"Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm":"JSON_ERROR"\}%';
-
-        // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
-        $this->assertRegExp(
-            $pattern,
+        $this->assertSame(
+            '{"function":"Monolog\\\\Formatter\\\\{closure}","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestFooNorm)","[resource(stream)]"]}',
             $result['context']['exception']['trace'][0]
         );
     }
@@ -449,6 +437,29 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
 
         return $message;
     }
+
+    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\TH:i:sP').'"]}',
+            $result['context']['exception']['trace'][0]
+        );
+    }
+
+    private function throwHelper($arg)
+    {
+        throw new \RuntimeException('Thrown');
+    }
 }
 
 class TestFooNorm
@@ -490,3 +501,11 @@ class TestToStringError
         throw new \RuntimeException('Could not convert to string');
     }
 }
+
+class TestInfoLeak
+{
+    public function __toString()
+    {
+        return 'Sensitive information';
+    }
+}