fix << on signed int warnings
<< on a negative number is undefined behaviour in C, and will trigger fuzzer warnings.
This commit is contained in:
parent
0f1e278dd9
commit
834acad825
@ -73,6 +73,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "binary.h"
|
||||
#include "unaryconst.h"
|
||||
@ -140,6 +141,15 @@ vips_boolean_build( VipsObject *object )
|
||||
g_assert_not_reached(); \
|
||||
}
|
||||
|
||||
#define FNLOOP( TYPE, FN ) { \
|
||||
TYPE * restrict left = (TYPE *) in[0]; \
|
||||
TYPE * restrict right = (TYPE *) in[1]; \
|
||||
int * restrict q = (int *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
q[x] = FN( left[x], right[x] ); \
|
||||
}
|
||||
|
||||
static void
|
||||
vips_boolean_buffer( VipsArithmetic *arithmetic,
|
||||
VipsPel *out, VipsPel **in, int width )
|
||||
@ -163,8 +173,30 @@ vips_boolean_buffer( VipsArithmetic *arithmetic,
|
||||
SWITCH( LOOP, FLOOP, ^ );
|
||||
break;
|
||||
|
||||
/* Special case: we need to be able to use VIPS_LSHIFT_INT().
|
||||
*/
|
||||
case VIPS_OPERATION_BOOLEAN_LSHIFT:
|
||||
SWITCH( LOOP, FLOOP, << );
|
||||
switch( vips_image_get_format( im ) ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
LOOP( unsigned char, << ); break;
|
||||
case VIPS_FORMAT_CHAR:
|
||||
FNLOOP( signed char, VIPS_LSHIFT_INT ); break;
|
||||
case VIPS_FORMAT_USHORT:
|
||||
LOOP( unsigned short, << ); break;
|
||||
case VIPS_FORMAT_SHORT:
|
||||
FNLOOP( signed short, VIPS_LSHIFT_INT ); break;
|
||||
case VIPS_FORMAT_UINT:
|
||||
LOOP( unsigned int, << ); break;
|
||||
case VIPS_FORMAT_INT:
|
||||
FNLOOP( signed int, VIPS_LSHIFT_INT ); break;
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
FLOOP( float, << ); break;
|
||||
case VIPS_FORMAT_DOUBLE:
|
||||
FLOOP( double, << ); break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
|
||||
case VIPS_OPERATION_BOOLEAN_RSHIFT:
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "pcolour.h"
|
||||
|
||||
@ -95,12 +96,12 @@ vips_LabQ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
||||
|
||||
/* Build a.
|
||||
*/
|
||||
l = (p[1] << 3) | ((lsbs >> 3) & 0x7);
|
||||
l = VIPS_LSHIFT_INT( p[1], 3) | ((lsbs >> 3) & 0x7);
|
||||
q[1] = (float) l * 0.125;
|
||||
|
||||
/* And b.
|
||||
*/
|
||||
l = (p[2] << 3) | (lsbs & 0x7);
|
||||
l = VIPS_LSHIFT_INT( p[2], 3) | (lsbs & 0x7);
|
||||
q[2] = (float) l * 0.125;
|
||||
|
||||
p += 4;
|
||||
|
@ -158,6 +158,18 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
q[x] = (p[x] << n) | (((p[x] & 1) << n) - (p[x] & 1)); \
|
||||
}
|
||||
|
||||
#define SHIFT_LEFT_SIGNED( ITYPE, OTYPE ) { \
|
||||
ITYPE * restrict p = (ITYPE *) in; \
|
||||
OTYPE * restrict q = (OTYPE *) out; \
|
||||
int n = ((int) sizeof( OTYPE ) << 3) - ((int) sizeof( ITYPE ) << 3); \
|
||||
\
|
||||
g_assert( sizeof( ITYPE ) < sizeof( OTYPE ) ); \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
q[x] = VIPS_LSHIFT_INT( p[x], n ) | \
|
||||
(((p[x] & 1) << n) - (p[x] & 1)); \
|
||||
}
|
||||
|
||||
/* Cast int types to an int type. We need to pass in the type of the
|
||||
* intermediate value, either uint or int, or we'll have problems with uint
|
||||
* sources turning -ve.
|
||||
@ -188,6 +200,21 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Int to int handling for signed int types.
|
||||
*/
|
||||
#define INT_INT_SIGNED( ITYPE, OTYPE, TEMP, CAST ) { \
|
||||
if( cast->shift && \
|
||||
sizeof( ITYPE ) > sizeof( OTYPE ) ) { \
|
||||
SHIFT_RIGHT( ITYPE, OTYPE ); \
|
||||
} \
|
||||
else if( cast->shift ) { \
|
||||
SHIFT_LEFT_SIGNED( ITYPE, OTYPE ); \
|
||||
} \
|
||||
else { \
|
||||
CAST_INT_INT( ITYPE, OTYPE, TEMP, CAST ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Cast float types to an int type.
|
||||
*/
|
||||
#define CAST_FLOAT_INT( ITYPE, OTYPE, TEMP, CAST ) { \
|
||||
@ -336,7 +363,7 @@ vips_cast_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop )
|
||||
|
||||
case VIPS_FORMAT_CHAR:
|
||||
BAND_SWITCH_INNER( signed char,
|
||||
INT_INT,
|
||||
INT_INT_SIGNED,
|
||||
CAST_REAL_FLOAT,
|
||||
CAST_REAL_COMPLEX );
|
||||
break;
|
||||
@ -350,7 +377,7 @@ vips_cast_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop )
|
||||
|
||||
case VIPS_FORMAT_SHORT:
|
||||
BAND_SWITCH_INNER( signed short,
|
||||
INT_INT,
|
||||
INT_INT_SIGNED,
|
||||
CAST_REAL_FLOAT,
|
||||
CAST_REAL_COMPLEX );
|
||||
break;
|
||||
@ -364,7 +391,7 @@ vips_cast_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop )
|
||||
|
||||
case VIPS_FORMAT_INT:
|
||||
BAND_SWITCH_INNER( signed int,
|
||||
INT_INT,
|
||||
INT_INT_SIGNED,
|
||||
CAST_REAL_FLOAT,
|
||||
CAST_REAL_COMPLEX );
|
||||
break;
|
||||
|
@ -418,7 +418,7 @@ vips_rect_hash( VipsRect *pos )
|
||||
* X discrimination is more important than Y, since
|
||||
* most tiles will have a similar Y.
|
||||
*/
|
||||
hash = pos->left ^ (pos->top << 16);
|
||||
hash = pos->left ^ VIPS_LSHIFT_INT( pos->top, 16 );
|
||||
|
||||
return( hash );
|
||||
}
|
||||
|
@ -123,6 +123,7 @@
|
||||
#include <limits.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "pconvolution.h"
|
||||
|
||||
@ -979,7 +980,7 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
if( convi->exp > 0 )
|
||||
int_value = (int_sum + (1 << (convi->exp - 1))) >> convi->exp;
|
||||
else
|
||||
int_value = int_sum << convi->exp;
|
||||
int_value = VIPS_LSHIFT_INT( int_sum, convi->exp );
|
||||
int_value = VIPS_CLIP( 0, int_value, 255 );
|
||||
|
||||
if( VIPS_ABS( true_value - int_value ) > 2 ) {
|
||||
|
@ -406,7 +406,7 @@ read_1bit_binary( FILE *fp, VipsImage *out )
|
||||
for( y = 0; y < out->Ysize; y++ ) {
|
||||
for( x = 0; x < out->Xsize * out->Bands; x++ ) {
|
||||
buf[x] = (bits & 128) ? 0 : 255;
|
||||
bits <<= 1;
|
||||
bits = VIPS_LSHIFT_INT( bits, 1 );
|
||||
if( (x & 7) == 7 )
|
||||
bits = fgetc( fp );
|
||||
}
|
||||
@ -667,7 +667,7 @@ write_ppm_line_binary_squash( Write *write, VipsPel *p )
|
||||
bits = 0;
|
||||
n_bits = 0;
|
||||
for( x = 0; x < write->in->Xsize; x++ ) {
|
||||
bits <<= 1;
|
||||
bits = VIPS_LSHIFT_INT( bits, 1 );
|
||||
n_bits += 1;
|
||||
bits |= p[x] ? 0 : 1;
|
||||
|
||||
|
@ -1066,7 +1066,7 @@ rtiff_palette_line_bit( Rtiff *rtiff,
|
||||
}
|
||||
}
|
||||
else
|
||||
*q++ = i << (8 - bits_per_sample);
|
||||
*q++ = VIPS_LSHIFT_INT( i, 8 - bits_per_sample );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1245,7 +1245,7 @@ LabS2Lab16( VipsPel *q, VipsPel *p, int n )
|
||||
for( x = 0; x < n; x++ ) {
|
||||
/* TIFF uses unsigned 16 bit ... move zero, scale up L.
|
||||
*/
|
||||
q1[0] = (int) p1[0] << 1;
|
||||
q1[0] = VIPS_LSHIFT_INT( (int) p1[0], 1 );
|
||||
q1[1] = p1[1];
|
||||
q1[2] = p1[2];
|
||||
|
||||
|
@ -248,7 +248,8 @@ vips_image_paint_area( VipsImage *image, const VipsRect *r, const VipsPel *ink )
|
||||
|
||||
/* Rebuild RGBA, assuming little-endian.
|
||||
*/
|
||||
#define setRGBA( R, G, B, A ) (R | (G << 8) | (B << 16) | (A << 24))
|
||||
#define setRGBA( R, G, B, A ) \
|
||||
(R | (G << 8) | (B << 16) | ((guint32) A << 24))
|
||||
|
||||
/* OVER blend of two unpremultiplied RGBA guint32
|
||||
*
|
||||
|
@ -39,6 +39,14 @@
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* << on an int is undefined in C if the int is negative. Imagine a machine
|
||||
* that uses 1s complement, for example.
|
||||
*
|
||||
* Fuzzers find and warn about this, so we must use this macro instead. Cast
|
||||
* to uint, shift, and cast back.
|
||||
*/
|
||||
#define VIPS_LSHIFT_INT( I, N ) ((int) ((unsigned int) (I) << (N)))
|
||||
|
||||
/* What we store in the Meta hash table. We can't just use GHashTable's
|
||||
* key/value pairs, since we need to iterate over meta in Meta_traverse order.
|
||||
*
|
||||
|
@ -143,7 +143,7 @@ read24( const unsigned char *in, int remaining )
|
||||
|
||||
bits = 0;
|
||||
for( i = 0; i < 3; i++ ) {
|
||||
bits <<= 8;
|
||||
bits = VIPS_LSHIFT_INT( bits, 8 );
|
||||
if( remaining > 0 ) {
|
||||
bits |= in[i];
|
||||
remaining -= 1;
|
||||
@ -167,7 +167,7 @@ encode24( char *p, int bits, int remaining )
|
||||
/* Take the top 6 bits of 24.
|
||||
*/
|
||||
p[i] = b64_list[(bits >> 18) & 63];
|
||||
bits <<= 6;
|
||||
bits = VIPS_LSHIFT_INT( bits, 6 );
|
||||
remaining -= 6;
|
||||
}
|
||||
}
|
||||
@ -281,7 +281,7 @@ vips__b64_decode( const char *buffer, size_t *data_length )
|
||||
unsigned int val;
|
||||
|
||||
if( (val = b64_index[(int) buffer[i]]) != XX ) {
|
||||
bits <<= 6;
|
||||
bits = VIPS_LSHIFT_INT( bits, 6 );
|
||||
bits |= val;
|
||||
nbits += 6;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user