In tracing this down, I have found at least 2 problems.
One problem appears to be with image_exact but I have it even if I disable the image exact module. It's not getting the source filename properly, I'm not sure why, but this actually starts off a chain of events which cause the division by zero problem later on.
At modules/image_exact/image_exact.module:80 we see:
$source = file_create_path($node->images['_original']);
$node->images['_original'] is null for some reason. $node->images contains array ( '_original' => '', 'thumbnail' => '', 'preview' => '', ). This makes file_create_path() return 'files', which is a directory. This is the first problem and I don't know how to solve it.
Since this isn't a file (it's a directory), at modules/image_exact/image_exact.module:128, image_resize gets called with $destination as both the source and destination, and in this case it's the directory named 'files'. So the gd lib happily reads this dir as an image and tries to resize it and outputs a file which looks like a directory dumped in ascii.
At image_exact.module:106, should not just check if the file exists, you need to check if the file is an image with witdh/height greater than 0. This is the second problem.
Later on at modules/img_assist/img_assist.module:783, it tries to get the size of this image, but it's not an image, so it returns null. Therefore, the height, which is used at line 794 is 0 and this results in our division by zero error. Fixing the second problem will get ride of the div by zero. But image upload is still broken for some reason.
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | file.inc_6.patch | 3.57 KB | mgrant |
| #4 | file.inc_5.patch | 3.64 KB | mgrant |
| #3 | image_exact.module.patch | 1.2 KB | mgrant |
Comments
Comment #1
mgrant commentedI see suggestions on the php site to use getimagesize() or exif_imagetype() to check if a file is an image. exif_imagetype() is supposed to be faster but not sure if it works on all types of images.
Comment #2
mgrant commentedI fixed the first problem by adding this to php.ini:
upload_tmp_dir = "/tmp"
To find this, I wrote a test.php script to upload an image and print out $_FILES:
when I uploaded my file, I saw:
...
["error"]=>
array(1) {
["image"]=>
int(6)
}
...
error 6 (from this page http://fr.php.net/manual/en/features.file-upload.errors.php) is "Missing a temporary folder."
This solved my original problem. The outcome of this is that I see 2 bugs to fix:
1) the error from the post is not properly reported
2) image_exact should check if the file is indeed an image (see above)
Comment #3
mgrant commentedThis patch to image_exact.module let's the user know that the file being resize failed because it was run on a non-image file. I used getimagesize() to determine if it was an image.
Comment #4
mgrant commentedThis patch to file.inc tells the user why the upload failed. The bug was that the error checking was occuring only if the file was uploaded. I moved the error check before this if statement. I also added 2 new error conditions from php5.
I wanted to stop things before they got to the division by zero. The obvious thing is that the return value from file_check_upload() is false. However, nothing seems to listen to this return value. Here's what I see:
file_check_upload() is called in node.module at line 1574 like this:
function node_object_prepare(&$node) {
...
node_invoke($node, 'prepare'); <-- file_check_upload() is called here
node_invoke_nodeapi($node, 'prepare');
}
There's no way for node_object_prepare to return the fact that node_invoke() returned. I'll let someone more knowledgeble in the archetecture deal with this.
Comment #5
mgrant commentedI noticed an annoyance with the file.inc patch I just posted. If you edit the image later and change the title, you get an error 'The file image could not be saved, because the upload did not complete.' but the title is indeed changed.
Comment #6
mgrant commentedI fixed the annoyance, here is a better version of the file.inc patch.