oops, fix base64 encode/decode padding

we were adding up to two bytes of null to the end of base64-encoded
binary data due to a signed/unsigned mixup

add a test for this, plus a test for vips file format
This commit is contained in:
John Cupitt 2015-05-31 18:17:26 +01:00
parent 5d8440a265
commit baf78fc04a
4 changed files with 15 additions and 26 deletions

View File

@ -5,6 +5,7 @@
- vipsthumbnail uses vips_premultiply() for better alpha quality - vipsthumbnail uses vips_premultiply() for better alpha quality
- vips_copy() can turn 1xN or Nx1 M-band images into MxN one-band images - vips_copy() can turn 1xN or Nx1 M-band images into MxN one-band images
- added bandand() bandor() bandeor() convenience funcs to Python - added bandand() bandor() bandeor() convenience funcs to Python
- oops, base64 encode could pad by up to two zero bytes
7/5/15 started 8.0.3 7/5/15 started 8.0.3
- dzsave and tif pyr write could fail for some image dimensions, thanks Jonas - dzsave and tif pyr write could fail for some image dimensions, thanks Jonas

18
TODO
View File

@ -1,21 +1,3 @@
- extra character in exif-data?
try:
$ cd test
$ vipsheader -a images/IMG_4618.jpg | grep exif-data
exif-data: VIPS_TYPE_BLOB, data = 0x16e0a20, length = 6626
$ vips copy images/IMG_4618.jpg x.v
$ vipsheader -a x.v | grep exif-data
exif-data: VIPS_TYPE_BLOB, data = 0x20679f0, length = 6627
one byte longer!
fix, and add a test for exif length to test/test_foreign.py
- how about something like vips_grid() which turns a tall thin one-band - how about something like vips_grid() which turns a tall thin one-band
image into a much smaller many-band image? image into a much smaller many-band image?

View File

@ -64,6 +64,9 @@ Modified on:
25/3/11 25/3/11
- move to vips_ namespace - move to vips_ namespace
31/5/15
- oops siged/unsignned mess-up meant we were not padding correctly
*/ */
/* /*
@ -112,7 +115,7 @@ static unsigned char b64_index[256] = {
* end up with in[2] in the bottom few bits. * end up with in[2] in the bottom few bits.
*/ */
static int static int
read24( const unsigned char *in, size_t remaining ) read24( const unsigned char *in, int remaining )
{ {
int bits; int bits;
int i; int i;
@ -132,12 +135,12 @@ read24( const unsigned char *in, size_t remaining )
/* Output (up to) 24 bits as four base64 chars. Pad with '=' characters. /* Output (up to) 24 bits as four base64 chars. Pad with '=' characters.
*/ */
static void static void
encode24( char *p, int bits, size_t remaining ) encode24( char *p, int bits, int remaining )
{ {
int i; int i;
for( i = 0; i < 4; i++ ) { for( i = 0; i < 4; i++ ) {
if( remaining == 0 ) if( remaining <= 0 )
p[i] = '='; p[i] = '=';
else { else {
/* Take the top 6 bits of 24. /* Take the top 6 bits of 24.
@ -162,7 +165,7 @@ vips__b64_encode( const unsigned char *data, size_t data_length )
char *buffer; char *buffer;
char *p; char *p;
size_t i; int i;
int cursor; int cursor;
if( data_length == 0 ) { if( data_length == 0 ) {
@ -170,7 +173,8 @@ vips__b64_encode( const unsigned char *data, size_t data_length )
return( NULL ); return( NULL );
} }
if( output_data_length > 1024 * 1024 ) { if( output_data_length > 1024 * 1024 ) {
/* We shouldn't really be used for large amounts of data. /* We shouldn't really be used for large amounts of data, plus
* we are using int offsets.
*/ */
vips_error( "vips__b64_encode", "%s", _( "too much data" ) ); vips_error( "vips__b64_encode", "%s", _( "too much data" ) );
return( NULL ); return( NULL );
@ -183,7 +187,7 @@ vips__b64_encode( const unsigned char *data, size_t data_length )
cursor = 0; cursor = 0;
for( i = 0; i < data_length; i += 3 ) { for( i = 0; i < data_length; i += 3 ) {
size_t remaining = data_length - i; int remaining = data_length - i;
int bits; int bits;
bits = read24( data + i, remaining ); bits = read24( data + i, remaining );
@ -232,10 +236,11 @@ vips__b64_decode( const char *buffer, size_t *data_length )
unsigned char *p; unsigned char *p;
unsigned int bits; unsigned int bits;
int nbits; int nbits;
size_t i; int i;
if( output_data_length > 1024 * 1024 ) { if( output_data_length > 1024 * 1024 ) {
/* We shouldn't really be used for large amounts of data. /* We shouldn't really be used for large amounts of data, plus
* we are using an int for offset.
*/ */
vips_error( "vips__b64_decode", "%s", _( "too much data" ) ); vips_error( "vips__b64_decode", "%s", _( "too much data" ) );
return( NULL ); return( NULL );

View File

@ -113,6 +113,7 @@ class TestForeign(unittest.TestCase):
before_exif = self.colour.get_value("exif-data") before_exif = self.colour.get_value("exif-data")
after_exif = x.get_value("exif-data") after_exif = x.get_value("exif-data")
self.assertEqual(len(before_exif), len(after_exif))
for i in range(len(before_exif)): for i in range(len(before_exif)):
self.assertEqual(before_exif[i], after_exif[i]) self.assertEqual(before_exif[i], after_exif[i])