diff --git a/libvips/foreign/analyze2vips.c b/libvips/foreign/analyze2vips.c index 489d036f..c3802d8c 100644 --- a/libvips/foreign/analyze2vips.c +++ b/libvips/foreign/analyze2vips.c @@ -241,7 +241,7 @@ getstr( int mx, const char *str ) g_assert( mx < 256 ); - strncpy( buf, str, mx ); + vips_strncpy( buf, str, mx ); buf[mx]= '\0'; /* How annoying, patient_id has some funny ctrlchars in that mess up diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index 78301f44..89c65b50 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -71,8 +71,6 @@ * - support png8 palette write with palette, colours, Q, dither * 25/8/18 * - support xmp read/write - * 21/11/18 - * - save xmp as string, not blob */ /* @@ -277,18 +275,25 @@ vips__set_text( VipsImage *out, int i, const char *key, const char *text ) { char name[256]; - if( strcmp( key, "XML:com.adobe.xmp") == 0 ) - /* Save as an XMP tag. + if( strcmp( key, "XML:com.adobe.xmp" ) == 0 ) { + /* Save as an XMP tag. This must be a BLOB, for compatibility + * for things like the XMP blob that the tiff loader adds. + * + * Note that this will remove the null-termination from the + * string. We must carefully reattach this. */ - strncpy( name, VIPS_META_XMP_NAME, 256 ); - else - /* Save as a comment. Some PNGs have EXIF data as + vips_image_set_blob_copy( out, + VIPS_META_XMP_NAME, text, strlen( text ) ); + } + else { + /* Save as a string comment. Some PNGs have EXIF data as * text segments, but the correct way to support this is with * png_get_eXIf_1(). */ vips_snprintf( name, 256, "png-comment-%d-%s", i, key ); - vips_image_set_string( out, name, text ); + vips_image_set_string( out, name, text ); + } return( 0 ); } @@ -1098,12 +1103,22 @@ write_vips( Write *write, } if( vips_image_get_typeof( in, VIPS_META_XMP_NAME ) ) { - const char *str; + void *data; + size_t length; + char *str; - if( vips_image_get_string( in, VIPS_META_XMP_NAME, &str ) ) + /* XMP is attached as a BLOB with no null-termination. We + * must re-add this. + */ + if( vips_image_get_blob( in, + VIPS_META_XMP_NAME, &data, &length ) ) return( -1 ); + + str = g_malloc( length + 1 ); + vips_strncpy( str, data, length + 1 ); vips__png_set_text( write->pPng, write->pInfo, "XML:com.adobe.xmp", str ); + g_free( str ); } /* Set any "png-comment-xx-yyy" metadata items. diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index c371d439..08b9b5d4 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -279,7 +279,7 @@ vips_buf_appendns( VipsBuf *buf, const char *str, int sz ) */ cpy = VIPS_MIN( n, avail ); - strncpy( buf->base + buf->i, str, cpy ); + vips_strncpy( buf->base + buf->i, str, cpy ); buf->i += cpy; if( buf->i >= buf->mx - 4 ) { diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index e273e7fc..c4383437 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -241,7 +241,6 @@ class TestForeign: assert im.width == 290 assert im.height == 442 assert im.bands == 3 - assert im.get("xmp-data") == "sample xmp string" self.file_loader("pngload", PNG_FILE, png_valid) self.buffer_loader("pngload_buffer", PNG_FILE, png_valid)