[base] Always close user-provided stream.
The `FT_Open_Face` documentation states > If `FT_OPEN_STREAM` is set in `args->flags`, the stream in `args->stream` > is automatically closed before this function returns any error (including > `FT_Err_Invalid_Argument`). However, if the user provides a stream in `args.stream` with `FT_OPEN_STREAM` set and a `close` function, but then for some reason passes NULL for `aface` and a non-negative `face_index`, the error `Invalid_Argument` is returned but the `close` callback will not be called on the user-provided stream. This may cause resource leaks if the caller is depending on the `close` callback to free resources. The difficulty is that a user may fill out a `FT_StreamRec` and pass its address as `args.stream`, but the stream isn't really 'live' until `FT_Stream_New` is called on it (and `memory` is set). In particular, it cannot really be cleaned up properly in `ft_open_face_internal` until the stream pointer has been copied into the `stream` local variable. * src/base/ftobj.c (ft_open_face_internal): Ensure that user-provided `args.stream.close` is called even with early errors.
This commit is contained in:
parent
13983b058e
commit
0d4f887c79
@ -2544,7 +2544,7 @@
|
||||
|
||||
/* test for valid `library' delayed to `FT_Stream_New' */
|
||||
|
||||
if ( ( !aface && face_index >= 0 ) || !args )
|
||||
if ( !args )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
|
||||
@ -2555,6 +2555,14 @@
|
||||
if ( error )
|
||||
goto Fail3;
|
||||
|
||||
/* Do this error check after `FT_Stream_New` to ensure that the */
|
||||
/* 'close' callback is called. */
|
||||
if ( !aface && face_index >= 0 )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Fail3;
|
||||
}
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
/* If the font driver is specified in the `args' structure, use */
|
||||
|
Loading…
Reference in New Issue
Block a user