Commit 2e579f80e for imagemagick.org

commit 2e579f80e58bd57706950ac282d38deca7720e31
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Fri Nov 13 21:37:52 2026 +0100

    Serialize Graphviz calls in the DOT decoder (GHSA-f3r8-89f9-mx43)

diff --git a/coders/dot.c b/coders/dot.c
index 5dcd7504e..236c02d06 100644
--- a/coders/dot.c
+++ b/coders/dot.c
@@ -57,6 +57,7 @@
 #include "MagickCore/option.h"
 #include "MagickCore/resource_.h"
 #include "MagickCore/quantum-private.h"
+#include "MagickCore/semaphore.h"
 #include "MagickCore/static.h"
 #include "MagickCore/string_.h"
 #include "MagickCore/module.h"
@@ -67,6 +68,9 @@
 #include <gvc.h>
 static GVC_t
   *graphic_context = (GVC_t *) NULL;
+
+static SemaphoreInfo
+  *dot_semaphore = (SemaphoreInfo *) NULL;
 #endif

 #if defined(MAGICKCORE_GVC_DELEGATE)
@@ -137,6 +141,7 @@ static Image *ReadDOTImage(const ImageInfo *image_info,ExceptionInfo *exception)
   (void) AcquireUniqueFilename(read_info->filename);
   (void) FormatLocaleString(command,MagickPathExtent,"-Tsvg -o%s %s",
     read_info->filename,image_info->filename);
+  LockSemaphoreInfo(dot_semaphore);
 #if !defined(WITH_CGRAPH)
   graph=agread(GetBlobFileHandle(image));
 #else
@@ -144,6 +149,7 @@ static Image *ReadDOTImage(const ImageInfo *image_info,ExceptionInfo *exception)
 #endif
   if (graph == (graph_t *) NULL)
     {
+      UnlockSemaphoreInfo(dot_semaphore);
       (void) RelinquishUniqueFileResource(read_info->filename);
       read_info=DestroyImageInfo(read_info);
       return(DestroyImageList(image));
@@ -156,6 +162,7 @@ static Image *ReadDOTImage(const ImageInfo *image_info,ExceptionInfo *exception)
   gvRenderFilename(graphic_context,graph,(char *) "svg",read_info->filename);
   gvFreeLayout(graphic_context,graph);
   agclose(graph);
+  UnlockSemaphoreInfo(dot_semaphore);
   image=DestroyImageList(image);
   /*
     Read SVG graph.
@@ -211,6 +218,7 @@ ModuleExport size_t RegisterDOTImage(void)
   entry->flags^=CoderBlobSupportFlag;
   (void) RegisterMagickInfo(entry);
 #if defined(MAGICKCORE_GVC_DELEGATE)
+  dot_semaphore=AcquireSemaphoreInfo();
   graphic_context=gvContext();
 #endif
   return(MagickImageCoderSignature);
@@ -245,5 +253,7 @@ ModuleExport void UnregisterDOTImage(void)
       gvFreeContext(graphic_context);
       graphic_context=(GVC_t *) NULL;
     }
+  if (dot_semaphore != (SemaphoreInfo *) NULL)
+    RelinquishSemaphoreInfo(&dot_semaphore);
 #endif
 }