The image
crate offers a powerful and versatile core of operations for
encoding, decoding and manipulating images. It is used in game libraries,
graphics API bindings and, as the pool of Rust programs expands, even in
editors. It very recently reached 1.000.000 total downloads 🎉. Given
the scope of the project, it isn’t perfect and may never be, but it works for
many real world use cases and we are grateful for all the positive feedback we
get.
Many use cases for decoding pixel matrices involve an inherently untrustworthy environment. For instance a web browser may have to handle media sent by potentially shady servers, or an open image processing service on the web might receive malicious inputs. Rust’s safety guarantees help in this area, but don’t go far enough. Services can still be vulnerable to denial of service attacks caused by panics or resource exhaustion.
The versatility pushed down the priority of other engineering considerations,
but we’ve started to harden the library against malicious inputs via fuzzing.
For those who aren’t familiar, fuzzing refers to automated methods of finding
misbehaving inputs to programs. You can find out more in the documentation of
two prominent tools for Rust: afl.rs and cargo-fuzz. These
tools together have already been used to find and patch a significant number of
bugs in the png
, gif
and pnm
decoders.
It shouldn’t come as a surprise in today’s internet infrastructure that this is available as a service as well, very similar to hosting and CI. We’re also glad to announce that fuzzit.dev allows us to their platform as an open source organization. Thank you,
They have also been welcoming and helped out where possible with the setup. The
png
decoder in particular has been happily running and did not turn up
anything, while having generated a corpus of new test cases for CI – very
unique valid and invalid files.
It is worth adding that the work on fuzzing has applications beyond just having stability for trustless computation. Edges cases resulting from malformed inputs, misconfiguration, or just general mistakes can still cause program crashes if not properly addressed. This work helps prevent those sorts of bugs as well, resulting in a better, more robust library for all use cases.
A new configurable reader interface
So, how else can the newly released version 0.22.3
help?
This also brings us to the newly available interface for reading images:
image::io::Reader
. It unifies all previous functions into a single
builder and utility struct. This simplifies many operations such as reading an
image from memory with an automatically deduced type, or opening a file and
inspecting the path deduced format before processing, or overriding the guess
from the image
library.
The improved structure also opens up more possibilities for future versions. We plan on bringing a unified interface for configuring memory limits or maximum sizes so that there is no need to manually inspect potentially misleading metadata beforehand. We are also considering helpers for reading only parts of an image, potentially saving CPU time and I/O capacity. This was hard before due to concerns about the explosion of function combinations it would spawn.
The current version is intentionally somewhat minimal to avoid risks of breaking changes, so feel free to suggest new functionality you’d like to see. We’re open to feedback!