[babl] icc: make babl_space_from_icc threadsafe



commit c8d2ca843e10271c1532863f27dd8c7725085394
Author: Øyvind Kolås <pippin gimp org>
Date:   Wed Feb 3 01:08:27 2021 +0100

    icc: make babl_space_from_icc threadsafe
    
    When multiple threads concurrently try to use ICC profiles / spaces
    races during construction could cause broken internal representation of
    profiles.

 babl/babl-icc.c      | 21 +++++++++++++++++++++
 babl/babl-internal.c |  2 ++
 babl/babl-internal.h |  1 +
 3 files changed, 24 insertions(+)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 52a35d2a5..0bbb47e1d 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -957,6 +957,8 @@ babl_space_from_icc (const char   *icc_data,
 
   sign_t profile_class, color_space, pcs;
 
+  babl_mutex_lock (babl_space_mutex);
+
   if (!error) error = &int_err;
   *error = NULL;
 
@@ -973,13 +975,22 @@ babl_space_from_icc (const char   *icc_data,
     {
        ret = _babl_space_for_lcms (icc_data, icc_length);
        if (!ret)
+       {
+         babl_mutex_unlock (babl_space_mutex);
          return NULL;
+       }
        if (ret->space.icc_type == BablICCTypeCMYK)
+       {
+         babl_mutex_unlock (babl_space_mutex);
          return ret;
+       }
        ret->space.icc_length = icc_length;
        ret->space.icc_profile = malloc (icc_length);
        if (!ret->space.icc_profile)
+       {
+         babl_mutex_unlock (babl_space_mutex);
          return NULL;
+       }
        memcpy (ret->space.icc_profile, icc_data, icc_length);
 
 #ifdef HAVE_LCMS
@@ -1010,6 +1021,7 @@ babl_space_from_icc (const char   *icc_data,
        cmsCloseProfile (ret->space.cmyk.lcms_profile); // XXX keep it open in case of CMYK to CMYK 
transforms needed?
 #endif
        ret->space.icc_type = BablICCTypeCMYK;
+       babl_mutex_unlock (babl_space_mutex);
        return ret;
     }
 
@@ -1113,6 +1125,7 @@ babl_space_from_icc (const char   *icc_data,
   {
 
     babl_free (state);
+    babl_mutex_unlock (babl_space_mutex);
     return NULL;
   }
 
@@ -1130,6 +1143,7 @@ babl_space_from_icc (const char   *icc_data,
     ret->space.icc_profile = malloc (icc_length);
     memcpy (ret->space.icc_profile, icc_data, icc_length);
     babl_free (state);
+    babl_mutex_unlock (babl_space_mutex);
     return ret;
 
 
@@ -1175,6 +1189,7 @@ babl_space_from_icc (const char   *icc_data,
            *error = "Inconsistent ICC profile detected, profile contains both cLUTs and a matrix with 
swapped primaries, this likely means it is an intentionally inconsistent Argyll profile is in use; this 
profile is only capable of high accuracy rendering and does not permit acceleration for interactive 
previews.";
            fprintf (stderr, "babl ICC warning: %s\n", *error);
            babl_free (state);
+           babl_mutex_unlock (babl_space_mutex);
            return NULL;
         }
       }
@@ -1184,6 +1199,7 @@ babl_space_from_icc (const char   *icc_data,
      if (ret)
      {
         babl_free (state);
+        babl_mutex_unlock (babl_space_mutex);
         return ret;
      }
 
@@ -1199,6 +1215,7 @@ babl_space_from_icc (const char   *icc_data,
        ret->space.icc_length  = icc_length;
        ret->space.icc_profile = malloc (icc_length);
        memcpy (ret->space.icc_profile, icc_data, icc_length);
+       babl_mutex_unlock (babl_space_mutex);
        return ret;
      }
   }
@@ -1216,11 +1233,13 @@ babl_space_from_icc (const char   *icc_data,
      if (phosporant != 0)
      {
        *error = "unhandled phosporants, please report bug against babl with profile";
+       babl_mutex_unlock (babl_space_mutex);
        return NULL;
      }
      if (channels != 3)
      {
        *error = "unexpected non 3 count of channels";
+       babl_mutex_unlock (babl_space_mutex);
        return NULL;
      }
 
@@ -1250,6 +1269,7 @@ babl_space_from_icc (const char   *icc_data,
        ret->space.icc_profile = malloc (icc_length);
        memcpy (ret->space.icc_profile, icc_data, icc_length);
 
+       babl_mutex_unlock (babl_space_mutex);
        return ret;
      }
   }
@@ -1257,6 +1277,7 @@ babl_space_from_icc (const char   *icc_data,
   }
 
   babl_free (state);
+  babl_mutex_unlock (babl_space_mutex);
   return NULL;
 }
 
diff --git a/babl/babl-internal.c b/babl/babl-internal.c
index f7939a1b3..94043d3c4 100644
--- a/babl/babl-internal.c
+++ b/babl/babl-internal.c
@@ -84,6 +84,7 @@ BablMutex *babl_format_mutex;
 BablMutex *babl_debug_mutex;
 #endif
 BablMutex *babl_reference_mutex;
+BablMutex *babl_space_mutex;
 
 void
 babl_internal_init (void)
@@ -93,6 +94,7 @@ babl_internal_init (void)
   babl_fish_mutex = babl_mutex_new ();
   babl_format_mutex = babl_mutex_new ();
   babl_reference_mutex = babl_mutex_new ();
+  babl_space_mutex = babl_mutex_new ();
 #if BABL_DEBUG_MEM
   babl_debug_mutex = babl_mutex_new ();
 #endif
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 56e95e4a2..8b8ebd64d 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -249,6 +249,7 @@ extern int   babl_in_fish_path;
 extern BablMutex *babl_format_mutex;
 extern BablMutex *babl_fish_mutex;
 extern BablMutex *babl_reference_mutex;
+extern BablMutex *babl_space_mutex;
 
 #define BABL_DEBUG_MEM 0
 #if BABL_DEBUG_MEM


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