improve file open error handling

better behaviour if you try to open a directory as an image
This commit is contained in:
John Cupitt 2020-03-05 15:30:37 +00:00
parent 68f766b482
commit 6117310c18
5 changed files with 21 additions and 14 deletions

View File

@ -535,7 +535,7 @@ vips_foreign_find_load( const char *name )
*/
if( !vips_existsf( "%s", filename ) ) {
vips_error( "VipsForeignLoad",
_( "file \"%s\" not found" ), name );
_( "file \"%s\" not readable" ), name );
return( NULL );
}

View File

@ -222,7 +222,7 @@ const void *vips_source_map( VipsSource *source, size_t *length );
VipsBlob *vips_source_map_blob( VipsSource *source );
gint64 vips_source_seek( VipsSource *source, gint64 offset, int whence );
int vips_source_rewind( VipsSource *source );
size_t vips_source_sniff_at_most( VipsSource *source,
gint64 vips_source_sniff_at_most( VipsSource *source,
unsigned char **data, size_t length );
unsigned char *vips_source_sniff( VipsSource *source, size_t length );
gint64 vips_source_length( VipsSource *source );

View File

@ -358,7 +358,7 @@ vips_tracked_malloc( size_t size )
* @flags: flags for open()
* @...: open mode
*
* Exactly as open(2), but the number of files current open via
* Exactly as open(2), but the number of files currently open via
* vips_tracked_open() is available via vips_tracked_get_files(). This is used
* by the vips operation cache to drop cache when the number of files
* available is low.

View File

@ -1203,7 +1203,7 @@ vips_source_length( VipsSource *source )
*
* Returns: number of bytes read, or -1 on error.
*/
size_t
gint64
vips_source_sniff_at_most( VipsSource *source,
unsigned char **data, size_t length )
{
@ -1263,7 +1263,9 @@ vips_source_sniff( VipsSource *source, size_t length )
return( NULL );
bytes_read = vips_source_sniff_at_most( source, &data, length );
if( bytes_read < (gint64) length )
if( bytes_read == -1 )
return( NULL );
if( bytes_read < length )
return( NULL );
return( data );

View File

@ -634,6 +634,14 @@ vips__open( const char *filename, int flags, ... )
mode = va_arg( ap, int );
va_end( ap );
/* Various bad things happen if you accidentally open a directory as a
* file.
*/
if( g_file_test( filename, G_FILE_TEST_IS_DIR ) ) {
errno = EISDIR;
return( -1 );
}
fd = g_open( filename, flags, mode );
#ifdef OS_WIN32
@ -1149,29 +1157,26 @@ vips__ftruncate( int fd, gint64 pos )
return( 0 );
}
/* TRUE if file exists.
/* TRUE if file exists and is not a directory.
*/
gboolean
vips_existsf( const char *name, ... )
{
va_list ap;
char *path;
int result;
gboolean result;
va_start( ap, name );
path = g_strdup_vprintf( name, ap );
va_end( ap );
result = g_access( path, R_OK );
/* A regular (not a directory) file.
*/
result = g_file_test( path, G_FILE_TEST_IS_REGULAR );
g_free( path );
/* access() can fail for various reasons, especially under things
* like selinux. Only return FALSE if we are certain the file does not
* exist.
*/
return( result == 0 ||
errno != ENOENT );
return( result );
}
#ifdef OS_WIN32