freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 0d4f887c7 2/3: [base] Always close user-provided stre


From: Werner Lemberg
Subject: [freetype2] master 0d4f887c7 2/3: [base] Always close user-provided stream.
Date: Tue, 17 Jan 2023 03:01:20 -0500 (EST)

branch: master
commit 0d4f887c790dc639902cb9ac89f9d099062530cb
Author: Ben Wagner <bungeman@chromium.org>
Commit: Werner Lemberg <wl@gnu.org>

    [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.
---
 src/base/ftobjs.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 7dcc7db58..cd20f374f 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -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 */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]