From 2d94fe732aa757c6d563b68103fb0d7c4df29f82 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 23 Jul 2018 14:55:37 +0100 Subject: [PATCH] escape ASCII control chars in xml stops some XML parse errors on corrupt metadata see https://github.com/jcupitt/libvips/issues/1039 --- ChangeLog | 1 + libvips/foreign/radiance.c | 3 +++ libvips/iofuncs/vips.c | 50 ++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b1db846..b8c44e16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,7 @@ - support writing string-valued fields via libexif - paste in the test suite from pyvips - get EXIF tag names from tag plus ifd [@Nan619] +- escape ASCII control characters in XML 12/3/18 started 8.6.4 - better fitting of fonts with overhanging edges [AdriĆ ] diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index 0ef1475c..4411abbf 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -24,6 +24,9 @@ * 22/7/18 * - update code from radiance ... pasted in from rad5R1 * - expand fs[] buffer to prevent out of bounds write [HongxuChen] + * 23/7/18 + * - fix a buffer overflow for incorrectly coded old-style RLE + * [HongxuChen] */ /* diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 81992337..f4dde475 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -23,6 +23,8 @@ * - validate strs as being utf-8 before we write * 9/4/18 Alexander-- * - use O_TMPFILE, if available + * 23/7/18 + * - escape ASCII control characters in XML */ /* @@ -769,38 +771,34 @@ dbuf_write_quotes( VipsDbuf *dbuf, const char *str ) } } -/* Append a string to a buffer, but escape &<>. +/* Append a string to a buffer, but escape &<> and the ASCII escape codes. Our + * argument string is utf-8. */ static void dbuf_write_amp( VipsDbuf *dbuf, const char *str ) { const char *p; - size_t len; - for( p = str; *p; p += len ) { - len = strcspn( p, "&<>" ); - - vips_dbuf_write( dbuf, (unsigned char *) p, len ); - switch( p[len] ) { - case '&': - vips_dbuf_writef( dbuf, "&" ); - len += 1; - break; - - case '<': - vips_dbuf_writef( dbuf, "<" ); - len += 1; - break; - - case '>': - vips_dbuf_writef( dbuf, ">" ); - len += 1; - break; - - default: - break; - } - } + for( p = str; *p; p++ ) + if( *p < 32 ) + /* You'd think we could output "%x;", but xml + * 1.0 parsers barf on that. Perhaps we should use '?', + * but this is frankly better. + * + * xml 1.1 allows this, but expat does not support + * it. + * + * vips_dbuf_writef( dbuf, "&#x%02x;", *p ); + */ + vips_dbuf_write( dbuf, (guchar *) "🐄", 9 ); + else if( *p == '<' ) + vips_dbuf_write( dbuf, (guchar *) "<", 4 ); + else if( *p == '>' ) + vips_dbuf_write( dbuf, (guchar *) ">", 4 ); + else if( *p == '&' ) + vips_dbuf_write( dbuf, (guchar *) "&", 5 ); + else + vips_dbuf_write( dbuf, (guchar *) p, 1 ); } static void *