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
- vips_copy() can turn 1xN or Nx1 M-band images into MxN one-band images
- 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
- 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
image into a much smaller many-band image?

View File

@ -64,6 +64,9 @@ Modified on:
25/3/11
- 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.
*/
static int
read24( const unsigned char *in, size_t remaining )
read24( const unsigned char *in, int remaining )
{
int bits;
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.
*/
static void
encode24( char *p, int bits, size_t remaining )
encode24( char *p, int bits, int remaining )
{
int i;
for( i = 0; i < 4; i++ ) {
if( remaining == 0 )
if( remaining <= 0 )
p[i] = '=';
else {
/* 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 *p;
size_t i;
int i;
int cursor;
if( data_length == 0 ) {
@ -170,7 +173,8 @@ vips__b64_encode( const unsigned char *data, size_t data_length )
return( NULL );
}
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" ) );
return( NULL );
@ -183,7 +187,7 @@ vips__b64_encode( const unsigned char *data, size_t data_length )
cursor = 0;
for( i = 0; i < data_length; i += 3 ) {
size_t remaining = data_length - i;
int remaining = data_length - i;
int bits;
bits = read24( data + i, remaining );
@ -232,10 +236,11 @@ vips__b64_decode( const char *buffer, size_t *data_length )
unsigned char *p;
unsigned int bits;
int nbits;
size_t i;
int i;
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" ) );
return( NULL );

View File

@ -113,6 +113,7 @@ class TestForeign(unittest.TestCase):
before_exif = self.colour.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)):
self.assertEqual(before_exif[i], after_exif[i])