Commit 945182d8 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

- Fix TOCTOU problem (utf8_stat -> fstat)

- Fix file descriptor leak when opening an empty file
- Don't close STDIN.
parent 51b87d9b
...@@ -50,8 +50,7 @@ ...@@ -50,8 +50,7 @@
#endif #endif
#if defined( WIN32 ) && !defined( UNDER_CE ) #if defined( WIN32 ) && !defined( UNDER_CE )
/* stat() support for large files on win32 */ /* fstat() support for large files on win32 */
# define stat _stati64
# define fstat(a,b) _fstati64(a,b) # define fstat(a,b) _fstati64(a,b)
# ifdef lseek # ifdef lseek
# undef lseek # undef lseek
...@@ -180,15 +179,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -180,15 +179,6 @@ static int Open( vlc_object_t *p_this )
strcpy( psz_name, p_access->psz_path + 1 ); strcpy( psz_name, p_access->psz_path + 1 );
} }
#endif #endif
#ifdef HAVE_SYS_STAT_H
if( utf8_stat( psz_name, &stat_info ) )
{
msg_Warn( p_access, "%s: %s", psz_name, strerror( errno ) );
free( psz_name );
return VLC_EGENERIC;
}
#endif
} }
STANDARD_READ_ACCESS_INIT; STANDARD_READ_ACCESS_INIT;
...@@ -201,6 +191,31 @@ static int Open( vlc_object_t *p_this ) ...@@ -201,6 +191,31 @@ static int Open( vlc_object_t *p_this )
p_sys->fd = -1; p_sys->fd = -1;
#endif #endif
msg_Dbg( p_access, "opening file `%s'", psz_name );
if( b_stdin )
p_sys->fd = dup(0);
else
_OpenFile( p_access, psz_name );
free( psz_name );
if( p_sys->fd == -1 )
{
free( p_sys );
return VLC_EGENERIC;
}
#ifdef HAVE_SYS_STAT_H
if( fstat( p_sys->fd, &stat_info ) )
{
msg_Err( p_access, "%s: %s", p_access->psz_path, strerror( errno ) );
close( p_sys->fd );
free( p_sys );
return VLC_EGENERIC;
}
#endif
if( !strcasecmp( p_access->psz_access, "stream" ) ) if( !strcasecmp( p_access->psz_access, "stream" ) )
{ {
p_sys->b_seekable = VLC_FALSE; p_sys->b_seekable = VLC_FALSE;
...@@ -218,61 +233,29 @@ static int Open( vlc_object_t *p_this ) ...@@ -218,61 +233,29 @@ static int Open( vlc_object_t *p_this )
p_sys->b_pace_control = VLC_TRUE; p_sys->b_pace_control = VLC_TRUE;
if( b_stdin ) if( b_stdin )
{
p_sys->b_seekable = VLC_FALSE; p_sys->b_seekable = VLC_FALSE;
} else
#ifdef UNDER_CE #if defined( HAVE_SYS_STAT_H )
else if( VLC_TRUE ) if( S_ISREG(stat_info.st_mode) || S_ISBLK(stat_info.st_mode)
{
/* We'll update i_size after it's been opened */
p_sys->b_seekable = VLC_TRUE;
}
#elif defined( HAVE_SYS_STAT_H )
else if( S_ISREG(stat_info.st_mode) || S_ISBLK(stat_info.st_mode)
|| ( S_ISCHR(stat_info.st_mode) && (stat_info.st_size > 0) ) ) || ( S_ISCHR(stat_info.st_mode) && (stat_info.st_size > 0) ) )
{ {
p_sys->b_seekable = VLC_TRUE; p_sys->b_seekable = VLC_TRUE;
p_access->info.i_size = stat_info.st_size; p_access->info.i_size = stat_info.st_size;
} }
else if( S_ISCHR(stat_info.st_mode) || S_ISFIFO(stat_info.st_mode) else
# ifdef S_ISSOCK
|| S_ISSOCK(stat_info.st_mode)
# endif
)
{
p_sys->b_seekable = VLC_FALSE; p_sys->b_seekable = VLC_FALSE;
} #else
/* We'll update i_size after it's been opened */
p_sys->b_seekable = VLC_TRUE;
#endif #endif
else
{
msg_Err( p_access, "unknown file type for `%s'", psz_name );
intf_UserFatal( p_access, VLC_FALSE, _("File reading failed"),
_("\"%s\"'s file type is unknown."),
psz_name );
free( psz_name );
return VLC_EGENERIC;
}
}
msg_Dbg( p_access, "opening file `%s'", psz_name );
if( b_stdin )
{
p_sys->fd = 0;
}
else if( _OpenFile( p_access, psz_name ) )
{
free( p_sys );
free( psz_name );
return VLC_EGENERIC;
} }
if( p_sys->b_seekable && !p_access->info.i_size ) if( p_sys->b_seekable && !p_access->info.i_size )
{ {
/* FIXME that's bad because all others access will be probed */ /* FIXME that's bad because all others access will be probed */
msg_Err( p_access, "file %s is empty, aborting", psz_name ); msg_Err( p_access, "file %s is empty, aborting", psz_name );
close( p_sys->fd );
free( p_sys ); free( p_sys );
free( psz_name );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment