[babl] babl_fish_reference(), create_name() are racy



commit 0fe22e1e37197ef6112645bf5a136580c0927a1e
Author: Roman Lebedev <lebedev ri gmail com>
Date:   Fri Aug 19 21:01:03 2016 +0300

    babl_fish_reference(), create_name() are racy
    
    create_name_internal() uses global static buffer to create name.
    While this is definitely fast, it can't work concurrently.
    
    I used snprintf()+malloc()+snprintf(), so the amount of allocated
    memory for the string is optimal.
    
    Alternatively, a mutex would solve the problem, not sure which
    solution is faster / better.

 babl/babl-fish-reference.c |   43 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 37 insertions(+), 6 deletions(-)
---
diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c
index 4133e40..fe75a71 100644
--- a/babl/babl-fish-reference.c
+++ b/babl/babl-fish-reference.c
@@ -31,17 +31,44 @@ assert_conversion_find (const void *source,
 }
 
 static char *
+create_name_internal (char *buf,
+                      size_t maxlen,
+                      const Babl *source,
+                      const Babl *destination,
+                      int   is_reference)
+{
+  return snprintf (buf, maxlen, "%s %p %p",
+                   is_reference ? "ref "
+                   : "",
+                   source, destination);
+}
+
+static char *
 create_name (const Babl *source,
              const Babl *destination,
              int   is_reference)
 {
-  static char buf[1024];
+  int size = 0;
+  char *buf = NULL;
+
+  size = create_name_internal (buf, size, source, destination, is_reference);
+
+  if (size < 0)
+    return NULL;
+
+  size++;             /* For '\0' */
+  buf = malloc (size);
+  if (buf == NULL)
+    return NULL;
+
+  size = create_name_internal (buf, size, source, destination, is_reference);
+
+  if (size < 0)
+    {
+      free (buf);
+      return NULL;
+    }
 
-  /* fish names are intentionally kept short */
-  snprintf (buf, 1024, "%s %p %p",
-            is_reference ? "ref "
-            : "",
-            source, destination);
   return buf;
 }
 
@@ -53,12 +80,15 @@ babl_fish_reference (const Babl *source,
   Babl *babl = NULL;
   char *name = create_name (source, destination, 1);
 
+  babl_assert (name);
+
   babl = babl_db_exist_by_name (babl_fish_db (), name);
   if (babl)
     {
       /* There is an instance already registered by the required name,
        * returning the preexistent one instead.
        */
+      free (name);
       return babl;
     }
 
@@ -87,6 +117,7 @@ babl_fish_reference (const Babl *source,
    * name, inserting newly created class into database.
    */
   babl_db_insert (babl_fish_db (), babl);
+  free (name);
   return babl;
 }
 


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