Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[Proposal / discussion] Optional libvips backend for webp_transform

Abierto
#13,773 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Necesita aclaración
Estado de actividad
Activo
Stack tecnológico
cmake, cpp

Línea de trabajo

Start with ImageTransform.cc and the proposed CMake builds, then review the libvips and ImageMagick backend trade-offs described in the issue. Done means reaching a decision on whether to pursue libvips, which plugin form to use, and how to handle licensing, RSS behavior, and the experimental/magick relationship.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

New Feature

This is a proposal for discussion, not a request to merge. It summarizes an evaluation of libvips as an alternative to ImageMagick for webp_transform, including trade-offs that argue against switching. Input from the community is wanted on whether to pursue it and in what form.

Motivation: attack surface

webp_transform decodes untrusted origin bodies on ET_NET threads. The case for libvips is security, not speed.

Advisory history, counted on the same basis for both libraries:

source ImageMagick libvips
NVD keyword match about 860 about 29 (many assigned by VulDB in 2026)
GitHub security advisories the 100 most recent span 2026-05-30 to 2026-09-27 12 in total, since 2023

ImageMagick:

  • Several recent advisories appear, from their descriptions, to be reachable through plain JPEG/PNG/WebP reads that a security policy cannot block. This has not been verified against the plugin's code path.
    • XMP profile parsing: DoS, infinite loop, use-after-free, over-read
    • JPEG decoder information disclosure
    • 8BIM use-after-free (identify path)
  • Image::read() sniffs the format itself, so a coder allowlist depends on a correct policy.xml.

libvips:

  • In a build with only jpeg/png/webp/exif enabled, one of the 12 GitHub advisories is reachable: an EXIF NULL dereference, fixed in 8.18.2.
  • The rest are in tiff, heif, svg, pdf, gif, radiance, ppm-source, the vips native format, and conversion ops the plugin doesn't call.
  • The plugin already knows the format from its signature check, so it can call vips_jpegload_buffer / vips_pngload_buffer / vips_webpload_buffer directly. libvips never sniffs.
  • vips_operation_block_set() can block every other loader as defence in depth.
  • New third-party parsers come with it: libexif (24 NVD entries, 4 in 2026; optional, though disabling it drops EXIF passthrough), lcms2 (needed only for CMYK JPEGs) and GLib.

Not a motivation: speed or output size

  • Throughput and CPU are a tie. libjpeg and libwebp do the work in both.
    • At matched quality, standalone per-image latency is within about ±10% across image classes (measured against ImageMagick 7.1.0-1).
    • Inside traffic_server with 16 clients, throughput is the same: 88–100 rps for ImageMagick 7.1.2-32 vs 92 rps for libvips, on 8 vCPU.
  • Output size at equal quality matches within 1–4%.

Memory: better per image, worse per process (open risk)

Peak memory per transcode is 28–48% lower with libvips. ImageMagick 7 (Q16 HDRI) holds pixels as floats.

image ImageMagick libvips
1920x1277 JPEG -> WebP 55 MB 29 MB

Inside traffic_server, process RSS is worse with libvips (jemalloc linked, default settings, 8 ET_NET threads, sustained transform load):

setup mean RSS
ImageMagick 411 MB
libvips 631 MB
libvips + jemalloc narenas:8 344 MB
ImageMagick + jemalloc narenas:8 351 MB
  • Cause: libvips does pixel work on its own worker threads. jemalloc's default of 4 arenas per CPU then keeps freed memory in many arenas. Allocator tuning closes the gap, but that is a process-wide setting.
  • Unknown: behaviour on hosts with many more cores.
  • Hazard: capping libvips' thread pool (VIPS_MAX_THREADS=8) hung traffic_server under load. The cause wasn't confirmed (no thread dump was taken). The plugin wouldn't set it, but it is a sharp edge.

Licensing

  • libvips and GLib are LGPL-2.1+, Category X under ASF policy.
  • A libvips backend can only be an optional, separately installed dependency, never bundled: "the component is only needed for optional features" (https://www.apache.org/legal/resolved.html).
  • webp_transform is already built only when its image library is found.

What a prototype looks like

  • Interface: a small Transcoder interface (init(), transcode()) with ImageMagick and libvips implementations. ImageTransform.cc keeps all HTTP logic.
  • Builds: CMake builds webp_transform.so (ImageMagick) and/or webp_transform_vips.so (libvips >= 8.13 via pkg-config).
  • libvips settings:
    • vips_concurrency_set(1)
    • vips_cache_set_max(0)
    • vips_block_untrusted_set(TRUE)
    • all loaders blocked except the three buffer loaders
    • sequential access with fail_on=error
    • dimensions checked from the header before any pixels are decoded
  • Behaviour matches the ImageMagick backend on the edge cases tested:
    • oversized, truncated and mislabeled bodies pass through
    • CMYK converts with lcms2 (colours differ slightly for CMYK files without an embedded profile)
    • EXIF orientation is preserved
  • Differences to account for:
    • Error log strings differ. webp_transform_decode_limit matches ImageMagick.. error.
    • libvips writes an EXIF block, so its JPEGs have no JFIF APP0 marker. webp_transform_invalid_input checks for JFIF.
    • Output quality must be explicit, because libvips has no source-quality estimate. This fits the quality proposal in #13772.

Related: experimental/magick

plugins/experimental/magick runs ImageMagick command lines (MagickCommandGenesis), which can't be ported to libvips. A libvips webp_transform would not remove ImageMagick from builds that enable experimental plugins.

Questions for discussion

  1. Is reduced attack surface worth an LGPL optional dependency (libvips + GLib) and a second backend to maintain?
  2. If yes, should libvips be an alternative build of the same plugin, a separate plugin, or eventually the only backend?
  3. Can we accept the RSS behaviour under default jemalloc settings, or would we need guidance or tuning? Data from larger hosts would help.
  4. Should experimental/magick stay as is, independent of this?

Method

  • Host: 8 vCPU (Ice Lake), EL9, gcc 11.
  • Libraries: ImageMagick 7.1.2-32 (Q16 HDRI, OpenMP, open policy; standalone latency also on 7.1.0-1); libvips 8.18.7 (meson, jpeg/png/webp/exif/lcms2 only).
  • Codecs: libwebp 1.2.0, libpng 1.6.37, libjpeg-turbo 2.0.90.
  • Corpus:
    • 36 web JPEGs (500–1920 px)
    • 24 Kodak PNGs
    • 8 RGBA logos
    • 28 WebP
    • edge cases
  • Test: traffic_server master (RelWithDebInfo, jemalloc 5.2.1), cache off for load runs, 16 clients for 60 s, RSS sampled every second.
  • Harness and full data available on request.
Lenguaje dominante
C++
Estrellas
2k
Forks
878
Merge medio
3 d 16 h
PR fusionados (30 d)
95

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de apache/trafficserver

Todos los issues de apache/trafficserver

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.