changeset 6647:983a74f5b875 machine-spirits

Fix possible overflow when rows/columns DICOM tags exceed the maximum value for a US (65535)
author Alain Mazy <am@orthanc.team>
date Tue, 03 Mar 2026 16:37:24 +0100
parents f1140bd7ed65
children dbc3ab1ce86a
files NEWS OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp OrthancFramework/Sources/Images/PamReader.cpp
diffstat 3 files changed, 20 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Mar 03 16:04:54 2026 +0100
+++ b/NEWS	Tue Mar 03 16:37:24 2026 +0100
@@ -144,6 +144,7 @@
     "TimeZoneOffsetFromUTC" is added to the "ExtraMainDicomTags" at Patient level.
     https://discourse.orthanc-server.org/t/jobs-api-the-dicommovescu-job-doesnt-seems-to-track-progress/3140/14
   - Fix possible overflow when calling /tools/create-dicom with a PAM file.
+  - Fix possible overflow when rows/columns DICOM tags exceed the maximum value for a US (65535).
 * Upgraded dependencies for static builds:
   - civetweb 1.16, including patch for CVE-2025-55763
   - SQLite 3.50.4
--- a/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp	Tue Mar 03 16:04:54 2026 +0100
+++ b/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp	Tue Mar 03 16:37:24 2026 +0100
@@ -42,6 +42,8 @@
 #include <stdio.h>
 #include <memory>
 
+static const uint64_t MAX_FRAME_SIZE = 4ul * 1024ul * 1024ul * 1024ul;  // defensive approach: set a reasonable max size for a frame
+
 namespace Orthanc
 {
   DicomImageInformation::DicomImageInformation(const DicomMap& values)
@@ -130,6 +132,11 @@
       values.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(width_); // in some US images, we've seen tag values of "800\0"; that's why we parse the 'first' value
       values.GetValue(DICOM_TAG_ROWS).ParseFirstUnsignedInteger(height_);
 
+      if (height_ > 65535 || width_ > 65535)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat, "Image width or height exceed DICOM VR US range (65535)");
+      }
+
       if (!values.ParseUnsignedInteger32(bitsAllocated_, DICOM_TAG_BITS_ALLOCATED))
       {
         throw OrthancException(ErrorCode_BadFileFormat);
@@ -470,10 +477,17 @@
     }
     else
     {
-      return (GetHeight() *
-              GetWidth() *
-              GetBytesPerValue() *
-              GetChannelCount());
+      uint64_t totalFrameSize = static_cast<uint64_t>(GetHeight()) * 
+                                GetWidth() *
+                                GetBytesPerValue() *
+                                GetChannelCount();
+
+      if (totalFrameSize > MAX_FRAME_SIZE)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat, "DICOM Frame size overflow");
+      }
+
+      return static_cast<size_t>(totalFrameSize);
     }
   }
 
--- a/OrthancFramework/Sources/Images/PamReader.cpp	Tue Mar 03 16:04:54 2026 +0100
+++ b/OrthancFramework/Sources/Images/PamReader.cpp	Tue Mar 03 16:37:24 2026 +0100
@@ -38,7 +38,7 @@
 #include <boost/algorithm/string/find.hpp>
 #include <boost/lexical_cast.hpp>
 
-static const uint64_t MAX_PAM_IMAGE_BUFFER_SIZE = 4ul * 1024ul * 1024ul * 1024ul;
+static const uint64_t MAX_PAM_IMAGE_BUFFER_SIZE = 4ul * 1024ul * 1024ul * 1024ul;  // defensive approach: set a reasonable max size for a PAM image
 
 namespace Orthanc
 {