App for Cloudflare® Pro

App for Cloudflare® Pro 1.8.9

Editing image doesn't show any image

When I try it with a a media image, it works as expected for me (I see it when using the Edit option).

Are you able to look in your devtools Network tab and see if there's any errors with any of the underlying HTTP requests? The image itself loads in via an AJAX request that starts with: wp-admin/admin-ajax.php?action=imgedit-preview. From the looks of it, it looks like the AJAX request is what's failing here for whatever reason.
 
When I try it with a a media image, it works as expected for me (I see it when using the Edit option).

Are you able to look in your devtools Network tab and see if there's any errors with any of the underlying HTTP requests? The image itself loads in via an AJAX request that starts with: wp-admin/admin-ajax.php?action=imgedit-preview. From the looks of it, it looks like the AJAX request is what's failing here for whatever reason.
No errors at all:
1729560814281.png
Console is empty:
1729560833560.png
The html is
1729560861659.png
and the src returns -1:
1729560881502.png
 
Is it specific to that image? Like are you able to see the image for other ones or are they not working across all of them?
 
Just for good measure, try flushing your Cloudflare Cache and trying it. Just to rule out it's a bad cache layer being served up.

FWIW, I've gone through more or less every Media image I have stored in WordPress (all in R2) as well as uploading brand new ones and immediately editing it, and they are all (old and new, including BRAND new) are showing the image when I go in to edit it. 🤔
 
I love how WordPress returns -1 what was is supposed to be actual error messages in some places. If you go into your wp-admin/includes/ajax-actions.php file, and look for the wp_ajax_imgedit_preview() function, you'll see two different wp_die( -1 ); calls within that function. Where it has -1 in those, change the -1 to something else/unique for each one so we can see which part might be the issue. Like maybe the first one to: 'current_user_cant_edit_post' and the second one to 'cant_stream_image'.

Then with devtools open again, try to edit it and see if the AJAX request gives you one of those errors instead of the -1. At least it would (hopefully) be something to look at further.

Sorry, I can't do it on my end... but without it doing it for me, I can't.
 
Okay... at least drilling down to what the underlying issue is. It looks like the stream_preview_image() function (in the wp-admin/includes/image-edit.php file) will fail under a couple circumstances:
  • The image itself can't load (either because it doesn't exist at the path it thinks it should be or WordPress can't figure out the type of image it is [either from its extension or actual contents]).
  • The image library that your PHP install is using (normally either GD or ImageMagick) fails when it tries to resize the image.
If you edit the above mentioned file, look for the stream_preview_image function and replace both cases of this:
PHP:
return false;

first one becomes this:
PHP:
print_r($img);

second one becomes this:
PHP:
print_r($img->resize($w2, $h2));

...and then edit/view AJAX request again.

With some luck, that should give a little better error (at least tell us what to narrow it down into next).
 
Okay... at least drilling down to what the underlying issue is. It looks like the stream_preview_image() function (in the wp-admin/includes/image-edit.php file) will fail under a couple circumstances:
  • The image itself can't load (either because it doesn't exist at the path it thinks it should be or WordPress can't figure out the type of image it is [either from its extension or actual contents]).
  • The image library that your PHP install is using (normally either GD or ImageMagick) fails when it tries to resize the image.
If you edit the above mentioned file, look for the stream_preview_image function and replace both cases of this:
PHP:
return false;

first one becomes this:
PHP:
print_r($img);

second one becomes this:
PHP:
print_r($img->resize($w2, $h2));

...and then edit/view AJAX request again.

With some luck, that should give a little better error (at least tell us what to narrow it down into next).
Got it, it is trying to load the file from localhost:
1729633892798.png
 
WordPress blocks the filter that transforms that into a URL if your PHP installation has allow_url_fopen disabled (it's enabled by default). Annoying, but it probably does make sense since PHP wouldn't allow it to be fetched.

Do you have access to your PHP config by chance?

At the very least, you could double check if that's what the issue is by creating a PHP file on your web server like so:

PHP:
<?php
phpinfo();

Could name it anything, and then run it/access it via your browser. At the top of the Core section, you will see what the allow_url_fopen directive is set to.
 
WordPress blocks the filter that transforms that into a URL if your PHP installation has allow_url_fopen disabled (it's enabled by default). Annoying, but it probably does make sense since PHP wouldn't allow it to be fetched.
Yes, allow_url_fopen is disabled because we are running on lsapi but it doesn't explain why other images load fine on Wordpress when we try to edit it. If allow_url_fopen is the issue then it should affect all images and that's not the case.
 
Are the images that are working still in the local filesystem possibly (maybe a backup was restored or something)? With allow_url_fopen disabled, WordPress *will* still try to load them, but it's trying to load them from the local filesystem rather than remotely.
 
Are the images that are working still in the local filesystem possibly
It happens with images which are in the filesystem but they don't show up when I try to edit them.
When allow_url_fopen all the images load but it's a security risk as well to left it enabled.
 
It really shouldn't be much of a security issue unless you are somehow allowing end users to manually specify files to load and end user input isn't getting sanitized. It was more a security issue back in the day when sites like MySpace would just let end users arbitrarily specify an absolute path on the server to something like an avatar image. And instead of specifying the path, they would make it a URL.

Blocking the use of URLs in fopen functions doesn't prevent PHP from making remote connections (for example the curl library does it). In the modern world, things aren't done that way anymore, so if a user is so deep into your system that they are maliciously using URL based fopen wrappers, they could also just use the curl functions instead. The least of the worries is them using fopen or curl, and the bigger worry is why they are able to do any of that to begin with. An infinitely bigger security risk is the fact that WordPress wants to have full write access to your filesystem.

That being said... I *do* wish WordPress didn't force the use of file_get_contents() for it's underlying reading of the images for the editor, but that's what they are doing and I have no control over WordPress core.
 
I'm going to keep sifting through WordPress code to see if there would be a way to intercept it's file_get_contents() call and swap it out with something better (like curl). But honestly, I'm not seeing anything so far.

In the meantime, I at least added a note at the top of the edit page for the next version that will present itself if the image is in R2 and the server has allow_url_fopen disabled (at least someone will know what's going on and how to fix it).
 
It really shouldn't be much of a security issue unless you are somehow allowing end users to manually specify files to load and end user input isn't getting sanitized. It was more a security issue back in the day when sites like MySpace would just let end users arbitrarily specify an absolute path on the server to something like an avatar image. And instead of specifying the path, they would make it a URL.
We host a few sites of some customers so my sysadmin says:
It's not a setting you want to enable as it will modify the behaviour for all customers to use a php.ini if it exists and the behaviour with the litespeed one is different to cpanels (IE it doesn't inherit all the settings from the main ini). It's not the recommended way to run and it's certainly not something we would suggest enabling to support this, it's simply not needed.

Change the app code to use something else, it will be faster than trying to work on adapting a shared hosting server to support a dangerous function.
 
While I don't agree that it's an actual security risk with WordPress, it certainly could be for other things if someone has poorly written code that doesn't validate or sanitize potentially malicious user input. I also 100% agree that there are better options to load files (or URLs) than file_get_contents(), and it most certainly wouldn't be what I would have used to do it.

The issue however is that WordPress' core is what is using file_get_contents() to load the image file that is presented via that AJAX request. It's in the WP_Image_Editor_GD::load() function, specifically this part is in WordPress core:

PHP:
$file_contents = @file_get_contents($this->file);

...so we are limited on being able to load the image (regardless if it's local or remote) via file_get_contents().

Basically the way WordPress is coded, it prevents us from swapping that function out with something better without going down the road of completely rewriting WordPress' entire image editing system from scratch.

Still looking at potentially hacky ways to make it work without allow_url_fopen, but so far those come with their own set of potential problems, for example reading an image from R2 and then writing that to the local filesystem before WordPress gets to it's part where it uses file_get_conetnts(). But then you start running into issues where you are trying to artificially manage a scheduling system where local files are scheduled to be deleted (for example 60 seconds into the future after they are written). Not a particularly great way to do it and adds a lot of weird things that could potentially go wrong so I don't particularly love that route.
 
Back
Top