Make WordPress Core

Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#35979 closed defect (bug) (fixed)

Specific URL text present in post or page contents may cause WP to run out of memory in the front-end

Reported by: fhoech's profile fhoech Owned by: dd32's profile dd32
Milestone: 4.5 Priority: normal
Severity: normal Version: 4.4
Component: Embeds Keywords: has-patch needs-testing commit
Focuses: Cc:

Description

When the following URL text (no HTML, I added code tags only to prevent Trac from displaying the URL as HTML link) is present in the contents of a WordPress post or page, WordPress may run out of memory when trying to view the post or page in the front-end, depending on the PHP memory limit.

http://www.homecinema-fr.com/colorimetre/release/DVD_V2.0.0.ISO

This URL points to an ISO disc image with a size of 63846400 bytes.
When this URL text is present in the contents of a post or page, e.g. with a WordPress install on a shared web host with limited memory, this can lead to an out of memory error like the following (the error is normally swallowed in the front-end, so unfortunately in the front-end the page just ends where the URL would be, but logging into the web host via SSH and running PHP from the command line allowed me to grab the error):

Fatal error: Allowed memory size of 125829120 bytes exhausted (tried to allocate 63846401 bytes) in wp-includes/class-oembed.php on line 345

As evidenced by the error message above, PHP tries to allocate 63846401 bytes, which is exactly the size of the ISO disc image + 1 byte, which leads me to believe WP actually tries to fetch the resource (or at least tries to allocate enough memory so it could fit the resource).

Example WordPress install exhibiting the problem:
http://wp.hoech.net/

The document ends after <div class="entry-content">, where normally the URL text would appear.

This probably affects WordPress from 4.4 (inclusive) onwards.

A way to work-around the problem is to install the "Disable Embeds" plug-in (https://wordpress.org/plugins/disable-embeds/).

Steps to reproduce:

  1. Have a PHP memory limit of 125829120 bytes or below.
  2. Have a clean WordPress 4.4.2 install (no plugins, default theme).
  3. Create a new page.
  4. Switch the editor to "text" mode.
  5. Paste the following URL into the editor:
    http://www.homecinema-fr.com/colorimetre/release/DVD_V2.0.0.ISO
    
  6. Publish the page.
  7. Try to view the page in the front-end.

Result:
The HTML document ends where the post contents should be (i.e. after <div class="entry-content"> when viewing page source).

Expected result:
The page should render completely.

Attachments (1)

35979.diff (2.6 KB) - added by dd32 9 years ago.

Download all attachments as: .zip

Change History (6)

@dd32
9 years ago

#1 @dd32
9 years ago

  • Keywords has-patch needs-testing added
  • Milestone changed from Awaiting Review to 4.5
  • Version changed from 4.4.2 to 4.4

35979.diff specifies the limit_response_size parameter for HTTP requests, that will cause it to only request a maximum of 150kb of data (the same limit we apply to Pingback verification requests).

The change to </head> detection is incase there's >150KB of data in the <head> (crazy, but plausible).

#2 @jorbin
9 years ago

  • Keywords commit added
  • Owner set to dd32
  • Status changed from new to assigned

This change looks good to me. 150kb seems like a sane amount.

#3 @dd32
9 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 36880:

oEmbed: During discovery, only request the first 150kb of linked content to avoid timouts requesting larger documents.

Fixes #35979.

#4 @TobiasBg
9 years ago

For that 150 KB magic number, could we use the KB_IN_BYTES constant (added in 4.4)? Or is that not yet available when that class is executed?

#5 @dd32
9 years ago

I wasn't aware of the KB_IN_BYTES constant, and the 150KB number is a randomly selected number we use elsewhere when retrieving pingback contents.

Note: See TracTickets for help on using tickets.