From abe4e70d02bae34d090db119ff387029129aeea2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 12 Mar 2016 15:10:52 +0000 Subject: [PATCH 1/2] make radload slightly more robust stops some valgrind warnings --- ChangeLog | 1 + doc/gtk-doc.make | 20 ++++++++++++-------- doc/libvips-docs.xml | 2 +- libvips/foreign/radiance.c | 36 +++++++++++++++++++++++++++++++----- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index b78391b1..68680286 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - fix a crash with SPARC byte-order labq vips images - fix parsing of filenames containing brackets, thanks shilpi230 - fix hist_entropy (lovell) +- small fixes to radiance load 12/1/16 started 8.2.2 - changes to ease compiling C++ binding with MSVC [Lovell Fuller] diff --git a/doc/gtk-doc.make b/doc/gtk-doc.make index e7916563..9ccd0b04 100644 --- a/doc/gtk-doc.make +++ b/doc/gtk-doc.make @@ -25,6 +25,7 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) SETUP_FILES = \ $(content_files) \ + $(expand_content_files) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt @@ -86,7 +87,7 @@ GTK_DOC_V_SETUP_0=@echo " DOC Preparing build"; setup-build.stamp: -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \ + files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ if test "x$$files" != "x" ; then \ for file in $$files ; do \ destdir=`dirname $(abs_builddir)/$$file`; \ @@ -118,7 +119,7 @@ scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ scanobj_options=""; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ scanobj_options="--verbose"; \ fi; \ @@ -162,17 +163,17 @@ GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V)) GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references"; -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkhtml_options="$$mkhtml_options --verbose"; \ fi; \ fi; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ fi; \ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) @@ -194,11 +195,11 @@ GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V)) GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_0=@echo " DOC Building PDF"; -pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ mkpdf_options=""; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkpdf_options="$$mkpdf_options --verbose"; \ fi; \ @@ -223,12 +224,15 @@ clean-local: @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ rm -f $(DOC_MODULE).types; \ fi + @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \ + rm -f $(DOC_MODULE)-sections.txt; \ + fi distclean-local: @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \ + rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ fi maintainer-clean-local: diff --git a/doc/libvips-docs.xml b/doc/libvips-docs.xml index fe88a909..2f631278 100644 --- a/doc/libvips-docs.xml +++ b/doc/libvips-docs.xml @@ -9,7 +9,7 @@ VIPS Reference Manual - For VIPS 8.2.2. + For VIPS 8.2.3. The latest version of this documentation can be found on the VIPS website. diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index 74be61bb..c50aae6e 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -653,16 +653,23 @@ buffer_need( Buffer *buffer, int require ) int remaining; g_assert( require < BUFFER_MARGIN ); + g_assert( buffer->length >= 0 ); + g_assert( buffer->position >= 0 ); + g_assert( buffer->position <= buffer->length ); remaining = buffer->length - buffer->position; if( remaining < require ) { size_t len; - memcpy( buffer->text, + /* Areas can overlap. + */ + memmove( buffer->text, buffer->text + buffer->position, remaining ); buffer->position = 0; buffer->length = remaining; + g_assert( buffer->length < BUFFER_MARGIN ); + len = fread( buffer->text + buffer->length, 1, BUFFER_SIZE, buffer->fp ); buffer->length += len; @@ -687,6 +694,10 @@ scanline_read_old( Buffer *buffer, COLR *scanline, int width ) { int rshift; + g_assert( buffer->length >= 0 ); + g_assert( buffer->position >= 0 ); + g_assert( buffer->position <= buffer->length ); + rshift = 0; while( width > 0 ) { @@ -728,6 +739,10 @@ scanline_read( Buffer *buffer, COLR *scanline, int width ) { int i, j; + g_assert( buffer->length >= 0 ); + g_assert( buffer->position >= 0 ); + g_assert( buffer->position <= buffer->length ); + /* Detect old-style scanlines. */ if( width < MINELEN || @@ -996,8 +1011,10 @@ static const char *colcor_name[3] = { static int rad2vips_get_header( Read *read, VipsImage *out ) { - int i, j; VipsInterpretation interpretation; + int width; + int height; + int i, j; if( getheader( read->fin, (gethfunc *) rad2vips_process_line, read ) || !fgetsresolu( &read->rs, read->fin ) ) { @@ -1013,9 +1030,17 @@ rad2vips_get_header( Read *read, VipsImage *out ) else interpretation = VIPS_INTERPRETATION_MULTIBAND; - vips_image_init_fields( out, - scanlen( &read->rs ), numscans( &read->rs ), - 4, + width = scanlen( &read->rs ); + height = numscans( &read->rs ); + if( width <= 0 || + width > VIPS_MAX_COORD || + height <= 0 || + height > VIPS_MAX_COORD ) { + vips_error( "rad2vips", "%s", _( "image size out of bounds" ) ); + return( -1 ); + } + + vips_image_init_fields( out, width, height, 4, VIPS_FORMAT_UCHAR, VIPS_CODING_RAD, interpretation, 1, read->aspect ); @@ -1080,6 +1105,7 @@ rad2vips_generate( VipsRegion *or, if( scanline_read( read->buffer, buf, or->im->Xsize ) ) { vips_error( "rad2vips", _( "read error line %d" ), r->top + y ); + VIPS_GATE_STOP( "rad2vips_generate: work" ); return( -1 ); } } From 6368ab06496b366d48cf7dcc1c7f767a94a70193 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 12 Mar 2016 16:48:27 +0000 Subject: [PATCH 2/2] add switches to disable rad, analyze and ppm vips has built-in support for rad, analyze and ppm ... add configure switches to disable these readers useful to reduce the attack surface in some applications --- ChangeLog | 1 + configure.ac | 30 ++++++++++++++++++++++++++++ libvips/deprecated/im_analyze2vips.c | 13 ++++++++---- libvips/foreign/analyze2vips.c | 3 +++ libvips/foreign/analyzeload.c | 4 ++++ libvips/foreign/foreign.c | 19 +++++++++++++----- libvips/foreign/ppm.c | 4 ++++ libvips/foreign/ppmload.c | 4 ++++ libvips/foreign/ppmsave.c | 4 ++++ libvips/foreign/radiance.c | 4 ++++ libvips/foreign/radload.c | 4 ++++ libvips/foreign/radsave.c | 4 ++++ test/test_foreign.py | 15 ++++++++++++++ 13 files changed, 100 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index ded22a71..019a53e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ - more vips_resize() tuning, a bit quicker now - better behaviour for vips_cast() shift of non-int types (thanks apacheark) - python .bandrank() now works like .bandjoin() +- switches to disable PPM, Rad and Analyze support 27/1/16 started 8.2.3 - fix a crash with SPARC byte-order labq vips images diff --git a/configure.ac b/configure.ac index 99199bda..949423fa 100644 --- a/configure.ac +++ b/configure.ac @@ -618,6 +618,33 @@ if test x"$with_matio" != "xno"; then ]) fi +# not external libraries, but have options to disable them, helps to +# reduce attack surface + +AC_ARG_WITH([ppm], + AS_HELP_STRING([--without-ppm], [build without ppm (default: with)])) + +if test x"$with_ppm" != "xno"; then + AC_DEFINE(HAVE_PPM,1,[define to build ppm support.]) + with_ppm=yes +fi + +AC_ARG_WITH([analyze], + AS_HELP_STRING([--without-analyze], [build without analyze (default: with)])) + +if test x"$with_analyze" != "xno"; then + AC_DEFINE(HAVE_ANALYZE,1,[define to build analyze support.]) + with_analyze=yes +fi + +AC_ARG_WITH([radiance], + AS_HELP_STRING([--without-radiance], [build without radiance (default: with)])) + +if test x"$with_radiance" != "xno"; then + AC_DEFINE(HAVE_RADIANCE,1,[define to build radiance support.]) + with_radiance=yes +fi + # cfitsio AC_ARG_WITH([cfitsio], AS_HELP_STRING([--without-cfitsio], [build without cfitsio (default: test)])) @@ -911,6 +938,9 @@ gobject introspection: $found_introspection build vips7 Python binding: $with_python install vips8 Python overrides: $enable_pyvips8 (requires pygobject-3.12.0 or later) +build radiance support: $with_radiance +build analyze support: $with_analyze +build PPM support: $with_ppm * optional dependencies use fftw3 for FFT: $with_fftw diff --git a/libvips/deprecated/im_analyze2vips.c b/libvips/deprecated/im_analyze2vips.c index f4d892c9..c7b63056 100644 --- a/libvips/deprecated/im_analyze2vips.c +++ b/libvips/deprecated/im_analyze2vips.c @@ -42,9 +42,6 @@ #include -#include "../foreign/dbh.h" -#include "../foreign/analyze2vips.h" - static VipsFormatFlags analyze_flags( const char *filename ) { @@ -61,7 +58,15 @@ isanalyze( const char *filename ) int im_analyze2vips( const char *filename, IMAGE *out ) { - return( vips__analyze_read( filename, out ) ); + VipsImage *t; + + if( vips_analyzeload( filename, &t, NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); return( 0 ); } diff --git a/libvips/foreign/analyze2vips.c b/libvips/foreign/analyze2vips.c index e7ec87b3..77771753 100644 --- a/libvips/foreign/analyze2vips.c +++ b/libvips/foreign/analyze2vips.c @@ -50,6 +50,8 @@ #endif /*HAVE_CONFIG_H*/ #include +#ifdef HAVE_ANALYZE + #include #include #include @@ -594,3 +596,4 @@ vips__analyze_read( const char *filename, VipsImage *out ) return( 0 ); } +#endif /*HAVE_ANALYZE*/ diff --git a/libvips/foreign/analyzeload.c b/libvips/foreign/analyzeload.c index 0bb1c6cd..691d1edc 100644 --- a/libvips/foreign/analyzeload.c +++ b/libvips/foreign/analyzeload.c @@ -48,6 +48,8 @@ #include #include +#ifdef HAVE_ANALYZE + #include "analyze2vips.h" typedef struct _VipsForeignLoadAnalyze { @@ -142,6 +144,8 @@ vips_foreign_load_analyze_init( VipsForeignLoadAnalyze *analyze ) { } +#endif /*HAVE_ANALYZE*/ + /** * vips_analyzeload: * @filename: file to load diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index a701c9e4..5ac52a63 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1665,22 +1665,31 @@ vips_foreign_operation_init( void ) extern GType vips_foreign_load_gif_file_get_type( void ); extern GType vips_foreign_load_gif_buffer_get_type( void ); - vips_foreign_load_rad_get_type(); - vips_foreign_save_rad_get_type(); - vips_foreign_load_ppm_get_type(); - vips_foreign_save_ppm_get_type(); vips_foreign_load_csv_get_type(); vips_foreign_save_csv_get_type(); vips_foreign_load_matrix_get_type(); vips_foreign_save_matrix_get_type(); vips_foreign_print_matrix_get_type(); - vips_foreign_load_analyze_get_type(); vips_foreign_load_raw_get_type(); vips_foreign_save_raw_get_type(); vips_foreign_save_raw_fd_get_type(); vips_foreign_load_vips_get_type(); vips_foreign_save_vips_get_type(); +#ifdef HAVE_ANALYZE + vips_foreign_load_analyze_get_type(); +#endif /*HAVE_ANALYZE*/ + +#ifdef HAVE_PPM + vips_foreign_load_ppm_get_type(); + vips_foreign_save_ppm_get_type(); +#endif /*HAVE_PPM*/ + +#ifdef HAVE_RADIANCE + vips_foreign_load_rad_get_type(); + vips_foreign_save_rad_get_type(); +#endif /*HAVE_RADIANCE*/ + #ifdef HAVE_POPPLER vips_foreign_load_pdf_get_type(); vips_foreign_load_pdf_file_get_type(); diff --git a/libvips/foreign/ppm.c b/libvips/foreign/ppm.c index bc5334ca..d6e4ecae 100644 --- a/libvips/foreign/ppm.c +++ b/libvips/foreign/ppm.c @@ -68,6 +68,8 @@ #endif /*HAVE_CONFIG_H*/ #include +#ifdef HAVE_PPM + #include #include #include @@ -825,3 +827,5 @@ vips__ppm_save( VipsImage *in, const char *filename, return( 0 ); } + +#endif /*HAVE_PPM*/ diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 55a5abaf..df458c9f 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -48,6 +48,8 @@ #include #include +#ifdef HAVE_PPM + #include "ppm.h" typedef struct _VipsForeignLoadPpm { @@ -142,6 +144,8 @@ vips_foreign_load_ppm_init( VipsForeignLoadPpm *ppm ) { } +#endif /*HAVE_PPM*/ + /** * vips_ppmload: * @filename: file to load diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 6893caee..178011af 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -47,6 +47,8 @@ #include +#ifdef HAVE_PPM + #include "ppm.h" typedef struct _VipsForeignSavePpm { @@ -144,6 +146,8 @@ vips_foreign_save_ppm_init( VipsForeignSavePpm *ppm ) { } +#endif /*HAVE_PPM*/ + /** * vips_ppmsave: * @in: image to save diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index c50aae6e..fc688b60 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -127,6 +127,8 @@ #endif /*HAVE_CONFIG_H*/ #include +#ifdef HAVE_RADIANCE + #include #include #include @@ -1303,3 +1305,5 @@ vips__rad_save( VipsImage *in, const char *filename ) } const char *vips__rad_suffs[] = { ".hdr", NULL }; + +#endif /*HAVE_RADIANCE*/ diff --git a/libvips/foreign/radload.c b/libvips/foreign/radload.c index 66ab5d55..8d46d3a7 100644 --- a/libvips/foreign/radload.c +++ b/libvips/foreign/radload.c @@ -48,6 +48,8 @@ #include #include +#ifdef HAVE_RADIANCE + #include "radiance.h" typedef struct _VipsForeignLoadRad { @@ -145,6 +147,8 @@ vips_foreign_load_rad_init( VipsForeignLoadRad *rad ) { } +#endif /*HAVE_RADIANCE*/ + /** * vips_radload: * @filename: file to load diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index cd97a67d..bfffe6c1 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -47,6 +47,8 @@ #include +#ifdef HAVE_RADIANCE + #include "radiance.h" typedef struct _VipsForeignSaveRad { @@ -129,6 +131,8 @@ vips_foreign_save_rad_init( VipsForeignSaveRad *rad ) { } +#endif /*HAVE_RADIANCE*/ + /** * vips_radsave: * @in: image to save diff --git a/test/test_foreign.py b/test/test_foreign.py index 9722e184..0eb44ff0 100755 --- a/test/test_foreign.py +++ b/test/test_foreign.py @@ -267,6 +267,11 @@ class TestForeign(unittest.TestCase): self.save_load("%s.webp", self.colour) def test_analyzeload(self): + x = Vips.type_find("VipsForeign", "analyzeload") + if not x.is_instantiatable(): + print("no analyze support in this vips, skipping test") + return + def analyze_valid(self, im): a = im(10, 10) self.assertAlmostEqual(a[0], 3335) @@ -416,10 +421,20 @@ class TestForeign(unittest.TestCase): self.save_load("%s.mat", self.mono) def test_ppm(self): + x = Vips.type_find("VipsForeign", "ppmload") + if not x.is_instantiatable(): + print("no PPM support in this vips, skipping test") + return + self.save_load("%s.ppm", self.mono) self.save_load("%s.ppm", self.colour) def test_rad(self): + x = Vips.type_find("VipsForeign", "radload") + if not x.is_instantiatable(): + print("no Radiance support in this vips, skipping test") + return + self.save_load("%s.hdr", self.colour) def test_dzsave(self):