[GH-ISSUE #1237] MongoDBFormatter can affect passed by reference arguments when writing trace to log #514

Open
opened 2026-03-04 02:15:38 +03:00 by kerem · 5 comments
Owner

Originally created by @FloatingMaster on GitHub (Dec 7, 2018).
Original GitHub issue: https://github.com/Seldaek/monolog/issues/1237

Steps to reproduce
Error handler:

public function handleError($type, $message, $file, $line) 
{
  $exception = new \ErrorException();
  $trace = $exception->getTrace();
  array_shift($trace);

  $this->getLogger()->log($this->errorTypeToLogLevel($type), $message, $trace)
}

Next in MongoDBFormatter::formatArray we have

foreach ($record as $name => $value) {
  ...
  } elseif (is_object($value)) {
    $record[$name] = $this->formatObject($value, $nestingLevel + 1);
  }
}

If there was any pass-by-reference arguments (e.g. foo(MyObj &$obj)) the object by reference will be replaced by formatted array.

Example:

public function testFoo()
{
  $a = new \stdClass();
    	
  var_dump($a);
  $this->foo($a);

  var_dump($a);

 }

public function foo(\stdClass &$a)
{
  $b = [];
  $b = $b['non-existing'];
}

Output:

class stdClass#134 (0) {
}
array(1) {
  'class' =>
  string(8) "stdClass"
}

Originally created by @FloatingMaster on GitHub (Dec 7, 2018). Original GitHub issue: https://github.com/Seldaek/monolog/issues/1237 **Steps to reproduce** Error handler: ``` public function handleError($type, $message, $file, $line) { $exception = new \ErrorException(); $trace = $exception->getTrace(); array_shift($trace); $this->getLogger()->log($this->errorTypeToLogLevel($type), $message, $trace) } ``` Next in MongoDBFormatter::formatArray we have ``` foreach ($record as $name => $value) { ... } elseif (is_object($value)) { $record[$name] = $this->formatObject($value, $nestingLevel + 1); } } ``` If there was any pass-by-reference arguments (e.g. `foo(MyObj &$obj)`) the object by reference will be replaced by formatted array. **Example:** ``` public function testFoo() { $a = new \stdClass(); var_dump($a); $this->foo($a); var_dump($a); } public function foo(\stdClass &$a) { $b = []; $b = $b['non-existing']; } ``` **Output**: ``` class stdClass#134 (0) { } array(1) { 'class' => string(8) "stdClass" } ```
Author
Owner

@Seldaek commented on GitHub (Dec 11, 2018):

This probably should be fixed (or at least checked if they are affected) for all normalizers.

<!-- gh-comment-id:446146837 --> @Seldaek commented on GitHub (Dec 11, 2018): This probably should be fixed (or at least checked if they are affected) for all normalizers.
Author
Owner

@juan-morales commented on GitHub (Oct 21, 2021):

But, in such a case, what is adviced to do here in order to "fix" this "issue"?

As far as I know , there is no reliable way to check if a variable is a reference in PHP, and "cloning just in case" is not an option.

Am I missing something here?

<!-- gh-comment-id:948576619 --> @juan-morales commented on GitHub (Oct 21, 2021): But, in such a case, what is adviced to do here in order to "fix" this "issue"? As far as I know , there is no reliable way to check if a variable is a reference in PHP, and "cloning just in case" is not an option. Am I missing something here?
Author
Owner

@Seldaek commented on GitHub (Oct 22, 2021):

It might just be about assigning things to a new array instead of the same to make sure we copy the stack trace and get rid of references.

I'm not sure either.. Doesn't seem like a super critical issue tbh, it's so unlikely to happen.

<!-- gh-comment-id:949428996 --> @Seldaek commented on GitHub (Oct 22, 2021): It might just be about assigning things to a new array instead of the same to make sure we copy the stack trace and get rid of references. I'm not sure either.. Doesn't seem like a super critical issue tbh, it's so unlikely to happen.
Author
Owner

@FloatingMaster commented on GitHub (Oct 22, 2021):

We solved the issue by recursivly converting record to array of simple type fields. Objects are converted to array through bsonSerialize, jsonSerialize or reflections

<!-- gh-comment-id:949524587 --> @FloatingMaster commented on GitHub (Oct 22, 2021): We solved the issue by recursivly converting record to array of simple type fields. Objects are converted to array through bsonSerialize, jsonSerialize or reflections
Author
Owner

@juan-morales commented on GitHub (Oct 22, 2021):

@FloatingMaster you applied that code on private code? Can we see it so we can better understand what was suppose to be done?

<!-- gh-comment-id:949863358 --> @juan-morales commented on GitHub (Oct 22, 2021): @FloatingMaster you applied that code on private code? Can we see it so we can better understand what was suppose to be done?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/monolog#514
No description provided.