stuff
This commit is contained in:
parent
d2a0d4468f
commit
74b0bf80ad
@ -360,10 +360,11 @@ typedef struct im__IMAGE {
|
||||
GSList *preclosefns; /* list of pre-close callbacks */
|
||||
GSList *invalidatefns; /* list of invalidate callbacks */
|
||||
|
||||
/* Set this to indicate a truncated file. We've been able to read the
|
||||
* header, but don't try reading outside the file size.
|
||||
/* Record the file length here. We use this to stop ourselves mapping
|
||||
* things beyond the end of the file in the case that the file has
|
||||
* been truncated.
|
||||
*/
|
||||
int nodata;
|
||||
size_t file_length;
|
||||
} IMAGE;
|
||||
|
||||
/* Only define if IM_ENABLE_DEPRECATED is set.
|
||||
|
@ -83,7 +83,6 @@ IMAGE *
|
||||
im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
||||
{
|
||||
IMAGE *im;
|
||||
gint64 length;
|
||||
gint64 psize;
|
||||
|
||||
/* Check parameters.
|
||||
@ -112,14 +111,14 @@ im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
||||
/* Read the file length and check against what we think
|
||||
* the size should be.
|
||||
*/
|
||||
if( (length = im_file_length( im->fd )) == -1 ) {
|
||||
if( (im->file_length = im_file_length( im->fd )) == -1 ) {
|
||||
im_close( im );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Very common, so special message.
|
||||
*/
|
||||
if( psize > length ) {
|
||||
if( psize > im->file_length ) {
|
||||
im_error( "im_binfile", _( "unable to open %s: "
|
||||
"file has been truncated" ), im->filename );
|
||||
im_close( im );
|
||||
@ -129,7 +128,7 @@ im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
||||
/* Just wierd. Only print a warning for this, since we should
|
||||
* still be able to process it without coredumps.
|
||||
*/
|
||||
if( psize < length )
|
||||
if( psize < im->file_length )
|
||||
im_warn( "im_binfile", _( "%s is longer than expected" ),
|
||||
im->filename );
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
* 9/8/08
|
||||
* - lock global image list (thanks lee)
|
||||
* 19/3/09
|
||||
* - add nodata
|
||||
* - add file_length
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -170,7 +170,7 @@ im_init( const char *filename )
|
||||
im->preclosefns = NULL;
|
||||
im->invalidatefns = NULL;
|
||||
|
||||
im->nodata = 0;
|
||||
im->file_length = 0;
|
||||
|
||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||
im_close( im );
|
||||
|
@ -210,7 +210,6 @@ im__munmap( void *start, size_t length )
|
||||
int
|
||||
im_mapfile( IMAGE *im )
|
||||
{
|
||||
gint64 length;
|
||||
struct stat st;
|
||||
mode_t m;
|
||||
|
||||
@ -219,15 +218,14 @@ im_mapfile( IMAGE *im )
|
||||
/* Check the size of the file; if it is less than 64 bytes, then flag
|
||||
* an error.
|
||||
*/
|
||||
if( (length = im_file_length( im->fd )) == -1 )
|
||||
return( -1 );
|
||||
g_assert( im->file_length > 0 );
|
||||
if( fstat( im->fd, &st ) == -1 ) {
|
||||
im_error( "im_mapfile",
|
||||
"%s", _( "unable to get file status" ) );
|
||||
return( -1 );
|
||||
}
|
||||
m = (mode_t) st.st_mode;
|
||||
if( length < 64 ) {
|
||||
if( im->file_length < 64 ) {
|
||||
im_error( "im_mapfile",
|
||||
"%s", _( "file is less than 64 bytes" ) );
|
||||
return( -1 );
|
||||
@ -238,13 +236,10 @@ im_mapfile( IMAGE *im )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !(im->baseaddr = im__mmap( im->fd, 0, length, 0 )) )
|
||||
if( !(im->baseaddr = im__mmap( im->fd, 0, im->file_length, 0 )) )
|
||||
return( -1 );
|
||||
|
||||
/* im__mmap() will fail for >2GB, so this is safe even for large
|
||||
* files.
|
||||
*/
|
||||
im->length = length;
|
||||
im->length = im->file_length;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -254,7 +249,6 @@ im_mapfile( IMAGE *im )
|
||||
int
|
||||
im_mapfilerw( IMAGE *im )
|
||||
{
|
||||
gint64 length;
|
||||
struct stat st;
|
||||
mode_t m;
|
||||
|
||||
@ -263,27 +257,23 @@ im_mapfilerw( IMAGE *im )
|
||||
/* Check the size of the file if it is less than 64 bytes return
|
||||
* make also sure that it is a regular file
|
||||
*/
|
||||
if( (length = im_file_length( im->fd )) == -1 )
|
||||
return( -1 );
|
||||
g_assert( im->file_length > 0 );
|
||||
if( fstat( im->fd, &st ) == -1 ) {
|
||||
im_error( "im_mapfilerw",
|
||||
"%s", _( "unable to get file status" ) );
|
||||
return( -1 );
|
||||
}
|
||||
m = (mode_t) st.st_mode;
|
||||
if( length < 64 || !S_ISREG( m ) ) {
|
||||
if( im->file_length < 64 || !S_ISREG( m ) ) {
|
||||
im_error( "im_mapfile",
|
||||
"%s", _( "unable to read data" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !(im->baseaddr = im__mmap( im->fd, 1, length, 0 )) )
|
||||
if( !(im->baseaddr = im__mmap( im->fd, 1, im->file_length, 0 )) )
|
||||
return( -1 );
|
||||
|
||||
/* im__mmap() will fail for >2GB, so this is safe even for large
|
||||
* files.
|
||||
*/
|
||||
im->length = length;
|
||||
im->length = im->file_length;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -325,14 +325,12 @@ read_chunk( int fd, gint64 offset, size_t length )
|
||||
int
|
||||
im__has_extension_block( IMAGE *im )
|
||||
{
|
||||
gint64 length;
|
||||
gint64 psize;
|
||||
|
||||
psize = im__image_pixel_length( im );
|
||||
if( (length = im_file_length( im->fd )) == -1 )
|
||||
return( 0 );
|
||||
g_assert( im->file_length > 0 );
|
||||
|
||||
return( length - psize > 0 );
|
||||
return( im->file_length - psize > 0 );
|
||||
}
|
||||
|
||||
/* Read everything after the pixels into memory.
|
||||
@ -340,29 +338,27 @@ im__has_extension_block( IMAGE *im )
|
||||
void *
|
||||
im__read_extension_block( IMAGE *im, int *size )
|
||||
{
|
||||
gint64 length;
|
||||
gint64 psize;
|
||||
void *buf;
|
||||
|
||||
psize = im__image_pixel_length( im );
|
||||
if( (length = im_file_length( im->fd )) == -1 )
|
||||
return( NULL );
|
||||
if( length - psize > 10 * 1024 * 1024 ) {
|
||||
g_assert( im->file_length > 0 );
|
||||
if( im->file_length - psize > 10 * 1024 * 1024 ) {
|
||||
im_error( "im_readhist",
|
||||
"%s", _( "more than a 10 megabytes of XML? "
|
||||
"sufferin' succotash!" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( length - psize == 0 )
|
||||
if( im->file_length - psize == 0 )
|
||||
return( NULL );
|
||||
if( !(buf = read_chunk( im->fd, psize, length - psize )) )
|
||||
if( !(buf = read_chunk( im->fd, psize, im->file_length - psize )) )
|
||||
return( NULL );
|
||||
if( size )
|
||||
*size = length - psize;
|
||||
*size = im->file_length - psize;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "im__read_extension_block: read %d bytes from %s\n",
|
||||
(int) (length - psize), im->filename );
|
||||
(int) (im->file_length - psize), im->filename );
|
||||
printf( "data: \"%s\"\n", (char *) buf );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
@ -896,7 +892,6 @@ im__read_header( IMAGE *image )
|
||||
*/
|
||||
unsigned char header[IM_SIZEOF_HEADER];
|
||||
|
||||
gint64 length;
|
||||
gint64 psize;
|
||||
|
||||
image->dtype = IM_OPENIN;
|
||||
@ -913,13 +908,11 @@ im__read_header( IMAGE *image )
|
||||
/* Predict and check the file size.
|
||||
*/
|
||||
psize = im__image_pixel_length( image );
|
||||
if( (length = im_file_length( image->fd )) == -1 )
|
||||
if( (image->file_length = im_file_length( image->fd )) == -1 )
|
||||
return( -1 );
|
||||
if( psize > length ) {
|
||||
if( psize > image->file_length )
|
||||
im_warn( "im_openin", _( "unable to read data for \"%s\", %s" ),
|
||||
image->filename, _( "file has been truncated" ) );
|
||||
image->nodata = 1;
|
||||
}
|
||||
|
||||
/* Set demand style. Allow the most permissive sort.
|
||||
*/
|
||||
@ -960,9 +953,13 @@ im_openin( IMAGE *image )
|
||||
if( im__read_header( image ) )
|
||||
return( -1 );
|
||||
|
||||
/* Make sure we can map the whole thing without running over the VM
|
||||
* limit or running out of file.
|
||||
*/
|
||||
size = (gint64) IM_IMAGE_SIZEOF_LINE( image ) * image->Ysize +
|
||||
image->sizeof_header;
|
||||
if( size < im__mmap_limit && !image->nodata ) {
|
||||
if( size < im__mmap_limit &&
|
||||
image->file_length >= size ) {
|
||||
if( im_mapfile( image ) )
|
||||
return( -1 );
|
||||
image->data = image->baseaddr + image->sizeof_header;
|
||||
|
@ -219,15 +219,6 @@ im_window_set( im_window_t *window, int top, int height )
|
||||
gint64 start, end, pagestart;
|
||||
size_t length, pagelength;
|
||||
|
||||
/* Make sure this image has data.
|
||||
*/
|
||||
if( window->im->nodata ) {
|
||||
im_error( "im_window_set",
|
||||
_( "unable to read data for \"%s\", %s" ),
|
||||
window->im->filename, _( "file has been truncated" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Calculate start and length for our window.
|
||||
*/
|
||||
start = window->im->sizeof_header +
|
||||
@ -238,6 +229,15 @@ im_window_set( im_window_t *window, int top, int height )
|
||||
end = start + length;
|
||||
pagelength = end - pagestart;
|
||||
|
||||
/* Make sure we have enough file.
|
||||
*/
|
||||
if( end > window->im->file_length ) {
|
||||
im_error( "im_window_set",
|
||||
_( "unable to read data for \"%s\", %s" ),
|
||||
window->im->filename, _( "file has been truncated" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !(baseaddr = im__mmap( window->im->fd, 0, pagelength, pagestart )) )
|
||||
return( -1 );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user