Closed dorianmariecom closed 2 years ago
From the original issue at https://github.com/libvips/libvips/issues/2620
We are facing the same issue with all jpg files. Below is the code that triggers the error with Rails ActiveStorage
User.cover_picture.variant(resize_to_fill: [640, 360]).processed
# => Vips::Error: VipsForeignLoad: "/tmp/ActiveStorage-3732-20220120-1268611-1q3jp07" is not a known file format
# VipsForeignLoad: "/tmp/ActiveStorage-3732-20220120-1268611-1q3jp07" is not a known file format
Happens on vips-8.4.5
and also vips-8.12.1
with image_processor version 1.12.1.
Here is a sample image that we are uplaoding:
I don't know what could be the issue. I would need a sample Rails app along with an image that reproduces the problem. Or a self-contained script using only ImageProcessing, without Active Storage.
Sure. I will prepare one and send in a day or two.
On 20. Jan 2022, at 19:05, Janko Marohnić @.***> wrote:
I don't know what could be the issue. I would need a sample Rails app along with an image that reproduces the problem. Or a self-contained script using only ImageProcessing, without Active Storage.
— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you commented.
@janko Here is a sample app: https://github.com/tsrivishnu/tmp-rails-libvips-jpg-failures that you can run in docker. The README has the instructions to run it in Docker. Make sure you adapt the Dockerfile as in the first point under Setup. Let me know if you are able to reproduce it.
Looks like the issue occurs only on Ubuntu bionic. I tried the same setup on Debian buster and it doesn't happen there.
Is there some way to verify that libvips has been compiled with JPEG support? What does running Vips.get_suffixes
return for you inside a Rails console in the Docker container?
I see the following in the Docker container where the variant creation fails
irb(main):007:0> Vips.get_suffixes
=> [".csv", ".mat", ".raw", ".v", ".vips", ".pbm", ".pgm", ".ppm", ".pfm", ".hdr", ".png"]
On the contrary, on a different container where it the variant creation succeeds:
irb(main):005:0> Vips.get_suffixes
=> [".csv", ".mat", ".raw", ".v", ".vips", ".ppm", ".pgm", ".pbm", ".pfm", ".hdr", ".dz", ".png", ".jpg", ".jpeg", ".jpe", ".webp", ".tif", ".tiff", ".fits", ".fit", ".fts", ".heic", ".heif", ".avif", ".gif", ".bmp"]
OK, this means the issue is neither in Active Storage nor in ImageProcessing, but in libvips provided by Ubuntu Bionic not being compiled with JPEG support.
For those who land on this issue looking for a solution:
Easiest option is to install libvips-dev
so that it installs all the require dependancies. This will install all the required libraries to support all the major file formats.
$ sudo apt-get install libvips-dev
If you are building libvips from source you need to install the optional dependancies yourself before you install libvips
. You will see in libvips
install instructions that it has many optional dependancies: https://www.libvips.org/install.html.
Pick the libraries required for the file formats you want to support or almost all of them with the following before you try to build from source. The following will install support for all major formats.
$ sudo apt-get install libjpeg-turbo8-dev \
libexif-dev \
libgif-dev \
librsvg2-dev \
libpoppler-glib-dev \
libtiff-dev \
libfftw3-dev \
libpng-dev \
liborc-0.4-dev \
libcfitsio-dev \
libwebp-dev \
libnifti-dev \
libheif-dev \
libopenslide-dev \
libgsf-1-dev \
libopenexr-dev \
libmatio-dev \
libmagickcore-dev \
libmagickwand-dev \
libimagequant-dev
Is there some way to verify that libvips has been compiled with JPEG support? What does running
Vips.get_suffixes
return for you inside a Rails console in the Docker container?
You can use --vips-config
, eg. I see:
$ vips --vips-config
enable debug: no
enable deprecated library components: yes
enable modules: no
use fftw3 for FFT: yes
accelerate loops with orc: yes
ICC profile support with lcms: yes (lcms2)
zlib: yes
text rendering with pangocairo: yes
font file support with fontconfig: yes
RAD load/save: yes
Analyze7 load/save: yes
PPM load/save: yes
GIF load: yes
GIF save with cgif: yes
EXIF metadata support with libexif: yes
JPEG load/save with libjpeg: yes (pkg-config)
JXL load/save with libjxl: no (dynamic module: no)
JPEG2000 load/save with libopenjp2: no
PNG load with libspng: no
PNG load/save with libpng: yes (pkg-config libpng >= 1.2.9)
quantisation to 8 bit: yes
TIFF load/save with libtiff: yes (pkg-config libtiff-4)
image pyramid save: yes
HEIC/AVIF load/save with libheif: yes (dynamic module: no)
WebP load/save with libwebp: yes
PDF load with PDFium: no
PDF load with poppler-glib: yes (dynamic module: no)
SVG load with librsvg-2.0: yes
EXR load with OpenEXR: yes
OpenSlide load: yes (dynamic module: no)
Matlab load with matio: yes
NIfTI load/save with niftiio: yes
FITS load/save with cfitsio: yes
Magick package: MagickCore (dynamic module: no)
Magick API version: magick6
load with libMagickCore: yes
save with libMagickCore: yes
Many of the load libraries that libvips can use are not very well tested and probably have vulnerabilities. The standard Debian and Ubuntu builds, for example, enable almost everything, and this makes them unsuitable for some applications.
If you are processing untrusted inputs (eg. a public web site) I would build your own libvips and only enable core formats. We fuzz with this set of loaders:
https://github.com/google/oss-fuzz/blob/master/projects/libvips/build.sh
Update alternatively, libvips 8.13 has a new feature which lets you disable untested loaders. Just set the env var VIPS_BLOCK_UNTRUSTED
and you can safely use any libvips binary.
See:
https://www.libvips.org/2022/05/28/What's-new-in-8.13.html#blocking-of-unfuzzed-loaders
Thank you @jcupitt
Why would an ActiveStorage::Blob.download
return ""
Does this means the file was not uploaded?
This is how the blob record looks like
#<ActiveStorage::Blob:0x00007fcffec70170
id: 9175,
key: "cyrlrcoiotkfyzhn923dz1elpm",
filename: "Image.jpeg",
content_type: "image/jpeg",
metadata: {"identified"=>true, "analyzed"=>true},
service_name: "amazon",
byte_size: 0,
checksum: "1B2M2Y8AsgTpgAmhCfg==",
created_at: Tue, 20 Sep 2022 00:42:27.524396000 UTC +00:00>
When you try to read the same file with vips you get this issue.
photos.first.blob.open do |file|
Vips::Image.new_from_file file.path
end
Error:
/Users/gathuku/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/ruby-vips-2.1.4/lib/vips/image.rb:281:in `new_from_file': VipsForeignLoad: "/var/folders/ch/8_2mrh555z9_19b8lzgkf44c0000gp/T/ActiveStorage-9175-20220926-91104-3ubaml.jpeg" is not a known file format (Vips::Error)
Hi,
I have been stumbling on this problem lately, as I understand it, the VipsForeignLoad
is raised when passing a file with a 0 byte_size (cf @gathuku example).
Vips::Error Exception: VipsForeignLoad:
"path/to/file/image_file_0ko.png" is not a known file format
This edge case works fine in with MiniMagick. If you use the active_storage_validation
gem, you can handle this use case with the processable_image
validator. I'll fix this issue in the active_storage_validation
gem in the coming days.
You can get zero-length files if you write to a file you're also reading. For example:
$ ls -l k2.png
-rw-r--r-- 1 john john 6126529 Dec 8 16:48 k2.png
$ vips copy k2.png k2.png
(vips:830444): VIPS-WARNING **: 16:48:13.378: not enough data
vips2png: unable to write to target k2.png
error buffer: vips2png: unable to write to target k2.png
$ ls -l k2.png
-rw-r--r-- 1 john john 0 Dec 8 16:48 k2.png
Could that be happening here somehow?
(this happens because libvips is lazy --- it won't process any pixels until they are really needed (to write the first byte of the output file in this case) and by the time you get to that point, the input file has already been deleted)
Hi @jcupitt,
In my context, it's all about reading a 0 byte file that has been inputed in a form.
At some point in the code we run Vips::Image.new_from_file(path)
with path being the uploaded file path, this code raises the mentioned error (Vips::Error Exception: VipsForeignLoad: "path/to/file/image_file_0ko.png" is not a known file format
). So we do not write, we only read.
Is this the normal behaviour?
Yes, that's expected behaviour. I think we used to special-case zero length files and have a different error message, but we removed it for simplicity.
Would you prefer a special message for this?
@jcupitt No it's fine for me. I will just catch this error to invalidate the fact that the image is processable and that's it. Thanks for your explanations.
Bug report
Describe the bug
Somehow when trying to process an image I got this error:
To Reproduce
Steps to reproduce the behavior:
attachment.file.variant(**options).processed
Expected behavior
Either says the file is not found somehow (maybe because of a server/dyno restart?) (I'm on Heroku), or maybe a missing package? not sure
Or actually process the file and return a new processed file
Actual behavior
Errors out
Environment
uname -a
)Linux c5450f47-0d17-4a40-8f95-2c64a40e8e2c 4.4.0-1097-aws #102-Ubuntu SMP Fri Sep 10 22:18:30 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
libvips
, probably the latest on the latest stable version of ubuntuAdditional context
I'm on a rails app, users can upload images, I process them (size, remove filenames, remove metadata, optimize, etc.)