Skip to content

[9.x] memory exhausted because JSON payload is unwanted parsed twice by Illuminate\Http\Request::createFromBase #42403

Closed
@MircoBabin

Description

@MircoBabin
  • Laravel Version: 9.12.2
  • PHP Version: PHP 8.1.4 (cli) (built: Mar 16 2022 09:33:31) (ZTS Visual C++ 2019 x64)
  • Database Driver & Version: MySql 8.0.16

Description:

I have an api POST route with json contents. Very unexpected this route was giving Allowed memory size of 134217728 bytes exhausted (tried to allocate ... bytes) errors.

To debug this issue:

  1. I adjusted public/index.php so the request would run to the end and would not be aborted by memory exhausted errors.
ini_set("memory_limit", "-1");
  1. I attached XDEBUG in profile mode.

  2. I replayed the request.

  3. I used QCacheGrind to visualize the profile:

image

As the profile shows, Illuminate\Http\Request::createFromBase via Request->json() calls json_decode() twice. Which is unwanted, because I don't use the Request::json() to retrieve the json contents. I do my own json_decode((string) Request::getContents()).

I did some digging in the Laravel History and found the commit introducing the json_decode behaviour in [9.x]: 13e4a7f The commit message states: ... This commit solves the underlying issue without breaking compatibility with the original functionality. ...

This commit is breaking compatibility, because it does not take memory consumption into account. Neither does it take performance into account, decoding the same request body twice is performance degradation. For large JSON (in my case Content-Length: 6428178) this can easily lead to memory exhausted errors. In Laravel 7.x there was no memory exhausted error.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions