Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,12 @@ function _getReferencedDisplaySetMetadata(referencedDisplaySet, segDisplaySet) {

const { PixelMeasuresSequence } = SharedFunctionalGroup;

const PixelMeasures = Array.isArray(PixelMeasuresSequence)
? PixelMeasuresSequence[0]
: PixelMeasuresSequence;
const PixelMeasures =
(Array.isArray(PixelMeasuresSequence) ? PixelMeasuresSequence[0] : PixelMeasuresSequence) || {};

if (!PixelMeasuresSequence || Object.keys(PixelMeasures).length === 0) {
console.warn('PixelMeasuresSequence missing from SEG instance metadata.');
}
Comment on lines 293 to +300

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard SharedFunctionalGroup before destructuring to avoid a remaining crash path.

On Line 293, const { PixelMeasuresSequence } = SharedFunctionalGroup; can still throw when SharedFunctionalGroupsSequence is missing/empty, so the new fallback on Lines 295–300 is never reached in that case. Please guard SharedFunctionalGroup first (and ideally fall back to per-frame pixel measures).

Proposed fix
 function _getReferencedDisplaySetMetadata(referencedDisplaySet, segDisplaySet) {
-  const { SharedFunctionalGroupsSequence } = segDisplaySet.instance;
+  const { SharedFunctionalGroupsSequence, PerFrameFunctionalGroupsSequence } = segDisplaySet.instance;

   const SharedFunctionalGroup = Array.isArray(SharedFunctionalGroupsSequence)
     ? SharedFunctionalGroupsSequence[0]
     : SharedFunctionalGroupsSequence;

-  const { PixelMeasuresSequence } = SharedFunctionalGroup;
+  const PerFrameFunctionalGroup = Array.isArray(PerFrameFunctionalGroupsSequence)
+    ? PerFrameFunctionalGroupsSequence[0]
+    : PerFrameFunctionalGroupsSequence;
+
+  const PixelMeasuresSequence =
+    SharedFunctionalGroup?.PixelMeasuresSequence ?? PerFrameFunctionalGroup?.PixelMeasuresSequence;

   const PixelMeasures =
     (Array.isArray(PixelMeasuresSequence) ? PixelMeasuresSequence[0] : PixelMeasuresSequence) || {};

   if (!PixelMeasuresSequence || Object.keys(PixelMeasures).length === 0) {
     console.warn('PixelMeasuresSequence missing from SEG instance metadata.');
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx`
around lines 293 - 300, Guard against a missing SharedFunctionalGroup before
destructuring: in OHIFCornerstoneSEGViewport, check that SharedFunctionalGroup
exists/truthy (and that SharedFunctionalGroupsSequence is present) before doing
"const { PixelMeasuresSequence } = SharedFunctionalGroup"; if it is missing,
fall back to extracting PixelMeasuresSequence from per-frame data (e.g.,
PerFrameFunctionalGroupsSequence or the first frame's FunctionalGroups) and then
compute PixelMeasures (PixelMeasuresSequence -> PixelMeasures) as before; update
the console warning to reflect which source was used (shared vs per-frame) and
ensure PixelMeasures is initialized to {} when neither source provides values to
avoid the crash.

const { SpacingBetweenSlices, SliceThickness } = PixelMeasures;

const image0 = referencedDisplaySet.images[0];
Expand Down
8 changes: 7 additions & 1 deletion platform/core/src/classes/MetadataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ class MetadataProvider {
return;
}

return (frameNumber && combineFrameInstance(frameNumber, instance)) || instance;
const combined = frameNumber && combineFrameInstance(frameNumber, instance);
if (combined) {
// Add imageId to multiframe result so it matches single-frame instance.
combined.imageId = imageId;
return combined;
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
return instance;
Comment on lines +63 to +69

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid mutating shared store instances when combineFrameInstance returns the original object.

This block assumes combined is isolated, but some paths can return the original instance; in those cases, assigning imageId here reintroduces shared metadata mutation.

💡 Suggested fix (isolate before assignment when needed)
-    const combined = frameNumber && combineFrameInstance(frameNumber, instance);
-    if (combined) {
-      // Add imageId to multiframe result so it matches single-frame instance.
-      combined.imageId = imageId;
-      return combined;
-    }
-    return instance;
+    const combined = frameNumber && combineFrameInstance(frameNumber, instance);
+    if (!combined) {
+      return instance;
+    }
+
+    // Some paths can return the original cached instance.
+    const result = combined === instance ? Object.create(instance) : combined;
+    result.imageId = imageId;
+    return result;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@platform/core/src/classes/MetadataProvider.ts` around lines 63 - 69, The code
assigns imageId to combined which can sometimes be the original shared instance
returned by combineFrameInstance; avoid mutating shared store objects by
checking if combined === instance and, if so, create a shallow copy (or an
isolated clone) before assigning imageId; update the logic around
combined/instance in MetadataProvider.ts (referencing combineFrameInstance,
combined, instance, imageId) so you only mutate a newly created object, then
return that copy, otherwise return the original instance unchanged.

}

get(query, imageId, options = { fallback: false }) {
Expand Down
Loading