commit:     a35f40615be53b528af4afd438c943ded78a45ba
Author:     Paul Zander <negril.nx+gentoo <AT> gmail <DOT> com>
AuthorDate: Fri Jul 18 10:50:35 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  1 08:08:06 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=a35f4061

media-gfx/netgen: backport PR202 crashfix

Signed-off-by: Paul Zander <negril.nx+gentoo <AT> gmail.com>
Part-of: https://github.com/gentoo/gentoo/pull/43083
Signed-off-by: Sam James <sam <AT> gentoo.org>

 media-gfx/netgen/files/netgen-PR202-std_map.patch | 137 ++++++++++++++++++++++
 media-gfx/netgen/netgen-6.2.2406-r1.ebuild        |   1 +
 media-gfx/netgen/netgen-6.2.2501-r1.ebuild        |   1 +
 3 files changed, 139 insertions(+)

diff --git a/media-gfx/netgen/files/netgen-PR202-std_map.patch 
b/media-gfx/netgen/files/netgen-PR202-std_map.patch
new file mode 100644
index 000000000000..d3d5e814131a
--- /dev/null
+++ b/media-gfx/netgen/files/netgen-PR202-std_map.patch
@@ -0,0 +1,137 @@
+From 78782dcd5365ec4aee54262373f12986e674f4b5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <[email protected]>
+Date: Thu, 19 Dec 2024 01:28:35 +0100
+Subject: [PATCH] Fix static initialization order for UserFormatRegister map
+
+A std::map is in an invalid state when just zero-initialized, and needs
+to be initialized by its constructor. As this initilization may be done
+after the first call to Register, a crash will typically happen.
+
+To fix this wrap all accesses to the map with a Meyers Singleton. Also
+remove the extra Array - most accesses are using the key, and the few
+format list iterations all sort the result afterwards anyway.
+
+Fixes #201.
+---
+ libsrc/interface/writeuser.cpp | 31 +++++++++++++++++++++++++------
+ libsrc/interface/writeuser.hpp | 25 ++++++++-----------------
+ libsrc/meshing/python_mesh.cpp |  4 +++-
+ 3 files changed, 36 insertions(+), 24 deletions(-)
+https://github.com/NGSolve/netgen/pull/202
+
+ diff --git a/libsrc/interface/writeuser.cpp b/libsrc/interface/writeuser.cpp
+index bfab7fbbf..637af7d36 100644
+--- a/libsrc/interface/writeuser.cpp
++++ b/libsrc/interface/writeuser.cpp
+@@ -16,19 +16,38 @@
+ 
+ namespace netgen
+ {
+-  extern MeshingParameters mparam;
++  std::map<std::string, UserFormatRegister::UserFormatEntry>& 
UserFormatRegister::getFormats()
++  {
++      static std::map<std::string, UserFormatRegister::UserFormatEntry> 
formats = {};
++      return formats;
++  }
+ 
+-  Array<UserFormatRegister::UserFormatEntry> UserFormatRegister::entries;
+-  std::map<string, int> UserFormatRegister::format_to_entry_index;
++  void UserFormatRegister::Register(UserFormatRegister::UserFormatEntry && 
entry)
++  {
++      getFormats()[entry.format] = std::move(entry);
++  }
++
++  const bool UserFormatRegister::HaveFormat(string format)
++  {
++      const auto formats = getFormats();
++      return formats.find(format) != formats.end();
++  }
++
++  const UserFormatRegister::UserFormatEntry & UserFormatRegister::Get(string 
format)
++  {
++      return getFormats()[format];
++  }
++
++  extern MeshingParameters mparam;
+ 
+   void RegisterUserFormats (NgArray<const char*> & names,
+                           NgArray<const char*> & extensions)
+                           
+ {
+-  for (const auto & entry : UserFormatRegister::entries)
++  for (const auto & entry : UserFormatRegister::getFormats())
+     {
+-      names.Append (entry.format.c_str());
+-      extensions.Append (entry.extensions[0].c_str());
++      names.Append (entry.second.format.c_str());
++      extensions.Append (entry.second.extensions[0].c_str());
+     }
+ }
+   
+diff --git a/libsrc/interface/writeuser.hpp b/libsrc/interface/writeuser.hpp
+index 99dc21e03..3d9a4e3af 100644
+--- a/libsrc/interface/writeuser.hpp
++++ b/libsrc/interface/writeuser.hpp
+@@ -28,32 +28,23 @@ struct UserFormatRegister {
+     optional<FRead> read;
+     optional<FWrite> write;
+   };
+-  DLL_HEADER static Array<UserFormatEntry> entries;
+-  DLL_HEADER static std::map<string, int> format_to_entry_index;
++  static void Register(UserFormatEntry && entry);
+ 
+-  static void Register(UserFormatEntry && entry) {
+-    format_to_entry_index[entry.format] = entries.Size();
+-    entries.Append( std::move(entry) );
+-  }
+-
+-  static const bool HaveFormat(string format) {
+-    return format_to_entry_index.count(format) > 0;
+-  }
+-  static const UserFormatEntry & Get(string format) {
+-    return entries[format_to_entry_index[format]];
+-  }
++  static const bool HaveFormat(string format);
++  DLL_HEADER static const UserFormatEntry & Get(string format);
+ 
+   template<typename TFunc>
+   static void IterateFormats(TFunc func, bool need_read=false, bool 
need_write=false) {
+     Array<string> import_formats;
+-    for(const auto & e: entries)
+-    if((!need_read || e.read) && (!need_write || e.write))
+-      import_formats.Append(e.format);
++    for(const auto & e: getFormats())
++    if((!need_read || e.second.read) && (!need_write || e.second.write))
++      import_formats.Append(e.second.format);
+     QuickSort(import_formats);
+     for(auto format : import_formats)
+-      func(entries[format_to_entry_index[format]]);
++      func(Get(format));
+   }
+ 
++  DLL_HEADER static std::map<std::string, UserFormatEntry>& getFormats();
+ };
+ 
+ struct RegisterUserFormat {
+diff --git a/libsrc/meshing/python_mesh.cpp b/libsrc/meshing/python_mesh.cpp
+index a771ba187..bbd9488a4 100644
+--- a/libsrc/meshing/python_mesh.cpp
++++ b/libsrc/meshing/python_mesh.cpp
+@@ -700,7 +700,8 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
+ 
+   string export_docu = "Export mesh to other file format. Supported formats 
are:\n";
+   Array<string> export_formats;
+-  for(auto & e : UserFormatRegister::entries)
++  for(auto & kv : UserFormatRegister::getFormats()) {
++    const auto e = kv.second;
+     if(e.write) {
+       string s = '\t'+e.format+"\t("+e.extensions[0];
+       for(auto & ext : e.extensions.Range(1, e.extensions.Size()))
+@@ -708,6 +709,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
+       s += ")\n";
+       export_formats.Append(s);
+     }
++  }
+   QuickSort(export_formats);
+   for(const auto & s : export_formats)
+     export_docu += s;

diff --git a/media-gfx/netgen/netgen-6.2.2406-r1.ebuild 
b/media-gfx/netgen/netgen-6.2.2406-r1.ebuild
index 0aec458d700c..cc1c82741dbd 100644
--- a/media-gfx/netgen/netgen-6.2.2406-r1.ebuild
+++ b/media-gfx/netgen/netgen-6.2.2406-r1.ebuild
@@ -74,6 +74,7 @@ PATCHES=(
        "${FILESDIR}/${PN}-6.2.2301-fix-nullptr-deref-in-archive.patch"
        "${FILESDIR}/${PN}-6.2.2406-encoding_h.patch"
        "${FILESDIR}/${PN}-6.2.2406-link-against-jpeg.patch"
+       "${FILESDIR}/${PN}-PR202-std_map.patch"
 )
 
 pkg_setup() {

diff --git a/media-gfx/netgen/netgen-6.2.2501-r1.ebuild 
b/media-gfx/netgen/netgen-6.2.2501-r1.ebuild
index 839921c4d9be..ab8c1f529bef 100644
--- a/media-gfx/netgen/netgen-6.2.2501-r1.ebuild
+++ b/media-gfx/netgen/netgen-6.2.2501-r1.ebuild
@@ -73,6 +73,7 @@ PATCHES=(
        # "${FILESDIR}/${PN}-6.2.2406-find-libjpeg-turbo-library.patch"
        "${FILESDIR}/${PN}-6.2.2301-fix-nullptr-deref-in-archive.patch"
        "${FILESDIR}/${PN}-6.2.2406-encoding_h.patch"
+       "${FILESDIR}/${PN}-PR202-std_map.patch"
 )
 
 pkg_setup() {

Reply via email to