changeset 7081:8b31c97470a5 streaming

reporting versions of third-party libraries and their associated patches
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 Aug 2026 17:01:38 +0200
parents 2663f94c5fc3
children 5205e2e5c3ae
files NEWS OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.7.0.cmake OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake OrthancFramework/Resources/CMake/OrthancFrameworkParameters.cmake OrthancFramework/Resources/CMake/PatchList.cpp.in OrthancFramework/Resources/CMake/PatchList.h.in OrthancServer/CMakeLists.txt OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.cpp OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.h OrthancServer/Sources/main.cpp
diffstat 12 files changed, 256 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Aug 12 15:14:35 2026 +0200
+++ b/NEWS	Wed Aug 12 17:01:38 2026 +0200
@@ -70,6 +70,8 @@
   - "OverwriteInstancesMode" (Boolean field "OverwriteInstances" is kept for backward compatibility)
   - "Performance" reports configuration options that may affect performance of Orthanc
   - "StoreMD5ForAttachments"
+  - "ThirdPartyPatches" lists the patches applied to the third-party libraries
+  - "ThirdPartyVersions" lists the versions of the main third-party libraries
 * The "LocalAet" field of the payload to "/modalities/../move", "/modalities/../store", 
   "/modalities/../get", "queries/../answers/../retrieve" now always overwrites the "DicomAet"
   and the "DicomModalities.LocalAet" configurations.
--- a/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake	Wed Aug 12 17:01:38 2026 +0200
@@ -47,6 +47,7 @@
   DownloadPackage(${CIVETWEB_MD5} ${CIVETWEB_URL} "${CIVETWEB_SOURCES_DIR}")
 
   if (FirstRun)
+    list(APPEND ORTHANC_PATCHES_LIST "civetweb-1.16.patch")
     execute_process(
       COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
       ${CMAKE_CURRENT_LIST_DIR}/../Patches/civetweb-1.16.patch
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.7.0.cmake	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.7.0.cmake	Wed Aug 12 17:01:38 2026 +0200
@@ -65,6 +65,7 @@
     message(FATAL_ERROR "Error while patching a file")
   endif()
 
+  list(APPEND ORTHANC_PATCHES_LIST "dcmtk-3.7.0-max-nested-sequence.patch")
   execute_process(
     COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
     ${CMAKE_CURRENT_LIST_DIR}/../Patches/dcmtk-3.7.0-max-nested-sequence.patch
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Wed Aug 12 17:01:38 2026 +0200
@@ -739,6 +739,32 @@
 
 
 #####################################################################
+## Publishing the list of the applied patches
+#####################################################################
+
+list(LENGTH ORTHANC_PATCHES_LIST ORTHANC_PATCHES_COUNT)
+
+if (ORTHANC_PATCHES_COUNT GREATER 0)
+  list(JOIN   ORTHANC_PATCHES_LIST "\",\n  \"" ORTHANC_PATCHES_C_BODY)
+  set(ORTHANC_PATCHES_C_BODY "\"${ORTHANC_PATCHES_C_BODY}\"")
+else()
+  set(ORTHANC_PATCHES_C_BODY "")
+endif()
+
+configure_file(
+  ${CMAKE_CURRENT_LIST_DIR}/PatchList.h.in
+  ${AUTOGENERATED_DIR}/PatchList.h
+  @ONLY
+  )
+
+configure_file(
+  ${CMAKE_CURRENT_LIST_DIR}/PatchList.cpp.in
+  ${AUTOGENERATED_DIR}/PatchList.cpp
+  @ONLY
+  )
+
+
+#####################################################################
 ## Gathering of all the source code
 #####################################################################
 
@@ -771,6 +797,8 @@
 
   ${CMAKE_CURRENT_LIST_DIR}/../../Resources/ThirdParty/md5/md5.c
   ${CMAKE_CURRENT_LIST_DIR}/../../Resources/ThirdParty/base64/base64.cpp
+
+  ${AUTOGENERATED_DIR}/PatchList.cpp
   )
 
 if (ENABLE_ZLIB)
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkParameters.cmake	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkParameters.cmake	Wed Aug 12 17:01:38 2026 +0200
@@ -111,6 +111,10 @@
 mark_as_advanced(USE_PUGIXML)
 
 
+# Must be filled with the list of patches applied to system-wide libraries (new in Orthanc 1.13.0)
+set(ORTHANC_PATCHES_LIST)
+
+
 #####################################################################
 ## Internal CMake parameters to enable the optional subcomponents of
 ## the Orthanc framework
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/CMake/PatchList.cpp.in	Wed Aug 12 17:01:38 2026 +0200
@@ -0,0 +1,32 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "PatchList.h"
+
+const char *const ORTHANC_PATCHES[] =
+{
+  @ORTHANC_PATCHES_C_BODY@
+};
+
+const unsigned int ORTHANC_PATCHES_COUNT = @ORTHANC_PATCHES_COUNT@;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/CMake/PatchList.h.in	Wed Aug 12 17:01:38 2026 +0200
@@ -0,0 +1,29 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+extern const char *const  ORTHANC_PATCHES[];
+
+extern const unsigned int ORTHANC_PATCHES_COUNT;
--- a/OrthancServer/CMakeLists.txt	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancServer/CMakeLists.txt	Wed Aug 12 17:01:38 2026 +0200
@@ -129,6 +129,7 @@
   ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/OrthancRestModalities.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/OrthancRestResources.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/OrthancRestSystem.cpp
+  ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/ThirdPartyVersions.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OrthancWebDav.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OutgoingDicomInstance.cpp
   ${CMAKE_SOURCE_DIR}/Sources/QueryRetrieveHandler.cpp
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Wed Aug 12 17:01:38 2026 +0200
@@ -32,6 +32,9 @@
 #include "../OrthancConfiguration.h"
 #include "../OrthancInitialization.h"
 #include "../ServerContext.h"
+#include "ThirdPartyVersions.h"
+
+#include <PatchList.h>
 
 #include <boost/algorithm/string/predicate.hpp>
 
@@ -89,6 +92,8 @@
     static const char* const HAS_EXTENDED_FIND = "HasExtendedFind";
     static const char* const HAS_RESERVE_QUEUE_VALUE = "HasReserveQueueValue";
     static const char* const PERFORMANCE = "Performance";
+    static const char* const THIRD_PARTY_PATCHES = "ThirdPartyPatches";
+    static const char* const THIRD_PARTY_VERSIONS = "ThirdPartyVersions";
 
     if (call.IsDocumentation())
     {
@@ -150,6 +155,10 @@
                         "Whether Patient level routes and sanity checks are enabled (new in Orthanc 1.12.11)")
         .SetAnswerField(PERFORMANCE, RestApiCallDocumentation::Type_JsonObject,
                         "The performance options from the configuration file, with sizes expressed in MB (new in Orthanc 1.13.0)")
+        .SetAnswerField(THIRD_PARTY_PATCHES, RestApiCallDocumentation::Type_JsonListOfStrings,
+                        "Patches applied to the third-party libraries included in this binary version of Orthanc (new in Orthanc 1.13.0)")
+        .SetAnswerField(THIRD_PARTY_VERSIONS, RestApiCallDocumentation::Type_JsonObject,
+                        "Versions of the third-party libraries (new in Orthanc 1.13.0)")
         .SetHttpGetSample("https://orthanc.uclouvain.be/demo/system", true);
       return;
     }
@@ -257,7 +266,26 @@
     result[CAPABILITIES][HAS_KEY_VALUE_STORES] = OrthancRestApi::GetIndex(call).HasKeyValueStoresSupport();
     result[CAPABILITIES][HAS_QUEUES] = OrthancRestApi::GetIndex(call).HasQueuesSupport();
     result[CAPABILITIES][HAS_RESERVE_QUEUE_VALUE] = OrthancRestApi::GetIndex(call).HasReserveQueueValueSupport();
-    
+
+    {
+      // New in Orthanc 1.13.0
+      Json::Value patches = Json::arrayValue;
+
+      for (unsigned int i = 0; i < ORTHANC_PATCHES_COUNT; i++)
+      {
+        patches.append(ORTHANC_PATCHES[i]);
+      }
+
+      result[THIRD_PARTY_PATCHES] = patches;
+    }
+
+    {
+      // New in Orthanc 1.13.0
+      Json::Value versions;
+      GetThirdPartyVersions(versions);
+      result[THIRD_PARTY_VERSIONS] = versions;
+    }
+
     call.GetOutput().AnswerJson(result);
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.cpp	Wed Aug 12 17:01:38 2026 +0200
@@ -0,0 +1,91 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeadersServer.h"
+#include "ThirdPartyVersions.h"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/version.hpp>
+#include <curl/curl.h>
+#include <png.h>
+#include <zlib.h>
+#include <sqlite3.h>
+#include <lua.h>
+#include <jpeglib.h>
+
+#if ORTHANC_ENABLE_CIVETWEB == 1
+#  include <civetweb.h>
+#endif
+
+#if ORTHANC_ENABLE_PUGIXML == 1
+#  include <pugixml.hpp>
+#endif
+
+namespace Orthanc
+{
+  void GetThirdPartyVersions(Json::Value& target)
+  {
+    target = Json::objectValue;
+
+    target["boost"] = (boost::lexical_cast<std::string>(BOOST_VERSION / 100000) + "." +
+                       boost::lexical_cast<std::string>(BOOST_VERSION / 100 % 1000) + "." +
+                       boost::lexical_cast<std::string>(BOOST_VERSION % 100));
+
+#if ORTHANC_ENABLE_CIVETWEB == 1
+    target["civetweb"] = (boost::lexical_cast<std::string>(CIVETWEB_VERSION_MAJOR) + "." +
+                          boost::lexical_cast<std::string>(CIVETWEB_VERSION_MINOR) + "." +
+                          boost::lexical_cast<std::string>(CIVETWEB_VERSION_PATCH));
+#endif
+
+    target["dcmtk"] = (boost::lexical_cast<std::string>(DCMTK_VERSION_NUMBER / 100) + "." +
+                       boost::lexical_cast<std::string>(DCMTK_VERSION_NUMBER / 10 % 10) + "." +
+                       boost::lexical_cast<std::string>(DCMTK_VERSION_NUMBER % 10));
+
+    target["jsoncpp"] = (boost::lexical_cast<std::string>(JSONCPP_VERSION_MAJOR) + "." +
+                         boost::lexical_cast<std::string>(JSONCPP_VERSION_MINOR) + "." +
+                         boost::lexical_cast<std::string>(JSONCPP_VERSION_PATCH));
+
+    target["libcurl"] = LIBCURL_VERSION;
+
+    target["libjpeg"] = (boost::lexical_cast<std::string>(JPEG_LIB_VERSION / 10) + "." +
+                         boost::lexical_cast<std::string>(JPEG_LIB_VERSION % 10));
+
+    target["libpng"] = (boost::lexical_cast<std::string>(PNG_LIBPNG_VER_MAJOR) + "." +
+                        boost::lexical_cast<std::string>(PNG_LIBPNG_VER_MINOR) + "." +
+                        boost::lexical_cast<std::string>(PNG_LIBPNG_VER_RELEASE));
+
+    target["lua"] = (boost::lexical_cast<std::string>(LUA_VERSION_MAJOR) + "." +
+                     boost::lexical_cast<std::string>(LUA_VERSION_MINOR) + "." +
+                     boost::lexical_cast<std::string>(LUA_VERSION_RELEASE));
+
+#if ORTHANC_ENABLE_PUGIXML == 1
+    target["pugixml"] = (boost::lexical_cast<std::string>(PUGIXML_VERSION / 1000) + "." +
+                         boost::lexical_cast<std::string>(PUGIXML_VERSION / 10 % 100) + "." +
+                         boost::lexical_cast<std::string>(PUGIXML_VERSION % 10));
+#endif
+
+    target["sqlite"] = SQLITE_VERSION;
+
+    target["zlib"] = ZLIB_VERSION;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.h	Wed Aug 12 17:01:38 2026 +0200
@@ -0,0 +1,31 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <json/value.h>
+
+namespace Orthanc
+{
+  void GetThirdPartyVersions(Json::Value& target);
+}
--- a/OrthancServer/Sources/main.cpp	Wed Aug 12 15:14:35 2026 +0200
+++ b/OrthancServer/Sources/main.cpp	Wed Aug 12 17:01:38 2026 +0200
@@ -56,6 +56,8 @@
 #include "ServerTranscoder.h"
 #include "StorageCommitmentReports.h"
 
+#include <PatchList.h>
+
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/program_options.hpp>
 
@@ -2444,6 +2446,11 @@
     LOG(WARNING) << "Orthanc version: " << version;
     assert(DisplayPerformanceWarning());
 
+    for (unsigned int i = 0; i < ORTHANC_PATCHES_COUNT; i++)
+    {
+      LOG(WARNING) << "This binary includes the following patch to a third-party library: " << ORTHANC_PATCHES[i];
+    }
+
     std::string s = "Architecture: ";
     if (sizeof(void*) == 4)
     {