add "unlimited" to jpegload
To disable DoS limits for JPEG loading. Adding API on a stable branch is bad, but this fixes a regression, so I think it's necessary, unfortunately. See https://github.com/libvips/libvips/issues/2973
This commit is contained in:
parent
a6fa62605c
commit
2c4c039056
1
.gitignore
vendored
1
.gitignore
vendored
@ -154,6 +154,7 @@ tmp-*
|
||||
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
TAGS
|
||||
### End of VIM
|
||||
|
||||
### Distribution
|
||||
|
@ -2,6 +2,7 @@
|
||||
- fix im7 feature detection in meson
|
||||
- add a summary table at the end of configure in meson
|
||||
- fix libpng fallback when spng is disabled in meson
|
||||
- add "unlimited" to jpegload
|
||||
|
||||
21/11/21 started 8.13
|
||||
- configure fails for requested but unmet dependencies [remicollet]
|
||||
|
@ -117,7 +117,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__jpeg_read_source( source, out,
|
||||
header_only, shrink, fail_on_warn, FALSE ) ) {
|
||||
header_only, shrink, fail_on_warn, FALSE, FALSE ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -112,6 +112,8 @@
|
||||
* - set resolution unit from JFIF
|
||||
* 24/7/21
|
||||
* - add fail_on support
|
||||
* 2/8/22
|
||||
* - add "unlimited"
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -169,6 +171,8 @@
|
||||
/* Stuff we track during a read.
|
||||
*/
|
||||
typedef struct _ReadJpeg {
|
||||
VipsImage *out;
|
||||
|
||||
/* Shrink by this much during load. 1, 2, 4, 8.
|
||||
*/
|
||||
int shrink;
|
||||
@ -190,6 +194,10 @@ typedef struct _ReadJpeg {
|
||||
*/
|
||||
gboolean autorotate;
|
||||
|
||||
/* Remove DoS limits.
|
||||
*/
|
||||
gboolean unlimited;
|
||||
|
||||
/* cinfo->output_width and height can be larger than we want since
|
||||
* libjpeg rounds up on shrink-on-load. This is the real size we will
|
||||
* output, as opposed to the size we decompress to.
|
||||
@ -251,8 +259,12 @@ source_fill_input_buffer( j_decompress_ptr cinfo )
|
||||
src->pub.bytes_in_buffer = bytes_read;
|
||||
}
|
||||
else {
|
||||
if( src->jpeg->fail_on >= VIPS_FAIL_ON_TRUNCATED )
|
||||
if( src->jpeg->fail_on >= VIPS_FAIL_ON_TRUNCATED ) {
|
||||
/* Knock the output out of cache.
|
||||
*/
|
||||
vips_foreign_load_invalidate( src->jpeg->out );
|
||||
ERREXIT( cinfo, JERR_INPUT_EOF );
|
||||
}
|
||||
else
|
||||
WARNMS( cinfo, JWRN_JPEG_EOF );
|
||||
|
||||
@ -317,6 +329,8 @@ readjpeg_open_input( ReadJpeg *jpeg )
|
||||
static void
|
||||
readjpeg_emit_message( j_common_ptr cinfo, int msg_level )
|
||||
{
|
||||
ReadJpeg *jpeg = (ReadJpeg *) cinfo->client_data;
|
||||
|
||||
long num_warnings;
|
||||
|
||||
if( msg_level < 0 ) {
|
||||
@ -325,11 +339,13 @@ readjpeg_emit_message( j_common_ptr cinfo, int msg_level )
|
||||
num_warnings = ++cinfo->err->num_warnings;
|
||||
|
||||
/* Corrupt files may give many warnings, the policy here is to
|
||||
* show only the first warning and treat many warnings as fatal.
|
||||
* show only the first warning and treat many warnings as fatal,
|
||||
* unless unlimited is set.
|
||||
*/
|
||||
if( num_warnings == 1 )
|
||||
(*cinfo->err->output_message)( cinfo );
|
||||
else if( num_warnings >= 100 )
|
||||
else if( !jpeg ||
|
||||
(!jpeg->unlimited && num_warnings >= 100) )
|
||||
cinfo->err->error_exit( cinfo );
|
||||
}
|
||||
else if( cinfo->err->trace_level >= msg_level )
|
||||
@ -381,13 +397,15 @@ readjpeg_minimise_cb( VipsImage *image, ReadJpeg *jpeg )
|
||||
|
||||
static ReadJpeg *
|
||||
readjpeg_new( VipsSource *source, VipsImage *out,
|
||||
int shrink, VipsFailOn fail_on, gboolean autorotate )
|
||||
int shrink, VipsFailOn fail_on, gboolean autorotate,
|
||||
gboolean unlimited )
|
||||
{
|
||||
ReadJpeg *jpeg;
|
||||
|
||||
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
||||
return( NULL );
|
||||
|
||||
jpeg->out = out;
|
||||
jpeg->source = source;
|
||||
g_object_ref( source );
|
||||
jpeg->shrink = shrink;
|
||||
@ -399,11 +417,8 @@ readjpeg_new( VipsSource *source, VipsImage *out,
|
||||
jpeg->eman.fp = NULL;
|
||||
jpeg->y_pos = 0;
|
||||
jpeg->autorotate = autorotate;
|
||||
|
||||
/* This is used by the error handlers to signal invalidate on the
|
||||
* output image.
|
||||
*/
|
||||
jpeg->cinfo.client_data = out;
|
||||
jpeg->unlimited = unlimited;
|
||||
jpeg->cinfo.client_data = jpeg;
|
||||
|
||||
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
||||
* readjpeg_free() since we don't want to jpeg_destroy_decompress().
|
||||
@ -982,12 +997,12 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
||||
int
|
||||
vips__jpeg_read_source( VipsSource *source, VipsImage *out,
|
||||
gboolean header_only, int shrink, VipsFailOn fail_on,
|
||||
gboolean autorotate )
|
||||
gboolean autorotate, gboolean unlimited )
|
||||
{
|
||||
ReadJpeg *jpeg;
|
||||
|
||||
if( !(jpeg = readjpeg_new( source, out, shrink, fail_on,
|
||||
autorotate )) )
|
||||
autorotate, unlimited )) )
|
||||
return( -1 );
|
||||
|
||||
/* Here for longjmp() from vips__new_error_exit() during
|
||||
|
@ -74,6 +74,10 @@ typedef struct _VipsForeignLoadJpeg {
|
||||
*/
|
||||
VipsSource *source;
|
||||
|
||||
/* Remove DoS limits.
|
||||
*/
|
||||
gboolean unlimited;
|
||||
|
||||
/* Shrink by this much during load.
|
||||
*/
|
||||
int shrink;
|
||||
@ -140,7 +144,7 @@ vips_foreign_load_jpeg_header( VipsForeignLoad *load )
|
||||
|
||||
if( vips__jpeg_read_source( jpeg->source,
|
||||
load->out, TRUE, jpeg->shrink, load->fail_on,
|
||||
jpeg->autorotate ) )
|
||||
jpeg->autorotate, jpeg->unlimited ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -153,7 +157,7 @@ vips_foreign_load_jpeg_load( VipsForeignLoad *load )
|
||||
|
||||
if( vips__jpeg_read_source( jpeg->source,
|
||||
load->real, FALSE, jpeg->shrink, load->fail_on,
|
||||
jpeg->autorotate ) )
|
||||
jpeg->autorotate, jpeg->unlimited ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -199,6 +203,13 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoadJpeg, autorotate ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "unlimited", 22,
|
||||
_( "Unlimited" ),
|
||||
_( "Remove all denial of service limits" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadJpeg, unlimited ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -153,7 +153,7 @@ int vips__jpeg_write_target( VipsImage *in, VipsTarget *target,
|
||||
|
||||
int vips__jpeg_read_source( VipsSource *source, VipsImage *out,
|
||||
gboolean header_only, int shrink, VipsFailOn fail_on,
|
||||
gboolean autorotate );
|
||||
gboolean autorotate, gboolean unlimited );
|
||||
int vips__isjpeg_source( VipsSource *source );
|
||||
|
||||
int vips__png_ispng_source( VipsSource *source );
|
||||
|
@ -173,12 +173,6 @@ vips__new_output_message( j_common_ptr cinfo )
|
||||
#ifdef DEBUG
|
||||
printf( "vips__new_output_message: \"%s\"\n", buffer );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* This is run for things like file truncated. Signal invalidate to
|
||||
* force this op out of cache.
|
||||
*/
|
||||
if( cinfo->client_data )
|
||||
vips_foreign_load_invalidate( VIPS_IMAGE( cinfo->client_data ) );
|
||||
}
|
||||
|
||||
/* New error_exit handler.
|
||||
|
@ -204,7 +204,7 @@ if test_supported matload; then
|
||||
# test blocked and untrusted
|
||||
printf "testing VIPS_BLOCK_UNTRUSTED with matio ... "
|
||||
export VIPS_BLOCK_UNTRUSTED=1
|
||||
if vips matload $matlab $tmp/block.png; then
|
||||
if $vips matload $matlab $tmp/block.png; then
|
||||
echo "failed to block matload"
|
||||
exit 1
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user