/** * CWE-407 simulation tests for ImageMagick defects. * * imagemagick-0001: UHDR coder GetImageListLength() O(N) called N times in loop = O(N^2) * imagemagick-0002: SyncImageList nested loop scene-number duplicate check = O(N^2) */ public class ImageMagickTest { // --------------------------------------------------------------- // imagemagick-0001: UHDR GetImageListLength in loop // --------------------------------------------------------------- /** Simulate a doubly-linked image list */ static class ImageNode { int scene; int depth; ImageNode next; ImageNode previous; ImageNode(int scene, int depth) { this.scene = scene; this.depth = depth; } } static ImageNode buildImageList(int n) { ImageNode head = new ImageNode(0, 8); ImageNode prev = head; for (int i = 1; i < n; i++) { ImageNode node = new ImageNode(i, 8); node.previous = prev; prev.next = node; prev = node; } return head; } /** O(N) traversal — simulates GetImageListLength */ static int getImageListLength(ImageNode image) { // Go to end first ImageNode p = image; while (p.next != null) p = p.next; // Count backwards int count = 0; while (p != null) { count++; p = p.previous; } return count; } /** DEFECTIVE: calls getImageListLength inside loop = O(N^2) */ static long writeUhdrDefective(ImageNode image) { long ops = 0; for (int i = 0; i < getImageListLength(image); i++) { ops += getImageListLength(image); // count traversal ops // simulate per-frame work if (image.next != null) image = image.next; } return ops; } /** FIXED: cache length before loop = O(N) */ static long writeUhdrFixed(ImageNode image) { long ops = 0; int numberScenes = getImageListLength(image); ops += numberScenes; // one traversal for (int i = 0; i < numberScenes; i++) { ops++; // per-frame work if (image.next != null) image = image.next; } return ops; } static void testUhdrGetImageListLength() { int N = 500; ImageNode list = buildImageList(N); long defectOps = writeUhdrDefective(list); long fixedOps = writeUhdrFixed(buildImageList(N)); double ratio = (double) defectOps / fixedOps; System.out.printf("imagemagick-0001 UHDR GetImageListLength in loop:%n"); System.out.printf(" N=%d defect_ops=%d fixed_ops=%d ratio=%.1fx%n", N, defectOps, fixedOps, ratio); assert ratio > 50.0 : "Expected significant overhead ratio, got " + ratio; System.out.println(" PASS"); } // --------------------------------------------------------------- // imagemagick-0002: SyncImageList O(N^2) scene dedup // --------------------------------------------------------------- /** DEFECTIVE: nested loop duplicate scene check O(N^2) */ static long syncImageListDefective(ImageNode images) { long ops = 0; ImageNode p, q; boolean hasDup = false; for (p = images; p != null; p = p.next) { for (q = p.next; q != null; q = q.next) { ops++; if (p.scene == q.scene) { hasDup = true; break; } } if (hasDup) break; } if (!hasDup) { // scenes are unique — no renumbering needed (worst case: full scan) } return ops; } /** FIXED: single-pass sequential check O(N) */ static long syncImageListFixed(ImageNode images) { long ops = 0; if (images == null || images.next == null) return 0; boolean needsRenumber = false; int expected = images.scene; for (ImageNode p = images.next; p != null; p = p.next) { ops++; expected++; if (p.scene != expected) { needsRenumber = true; break; } } if (needsRenumber) { for (ImageNode p = images.next; p != null; p = p.next) { ops++; p.scene = p.previous.scene + 1; } } return ops; } static void testSyncImageListDedup() { int N = 1000; // Build list with unique sequential scenes (worst case for defective) ImageNode list = buildImageList(N); long defectOps = syncImageListDefective(list); ImageNode list2 = buildImageList(N); long fixedOps = syncImageListFixed(list2); double ratio = (double) defectOps / fixedOps; System.out.printf("imagemagick-0002 SyncImageList scene dedup:%n"); System.out.printf(" N=%d defect_ops=%d fixed_ops=%d ratio=%.1fx%n", N, defectOps, fixedOps, ratio); assert ratio > 100.0 : "Expected significant overhead ratio, got " + ratio; System.out.println(" PASS"); } // --------------------------------------------------------------- // Main // --------------------------------------------------------------- public static void main(String[] args) { testUhdrGetImageListLength(); testSyncImageListDedup(); System.out.println("\nAll ImageMagick CWE-407 tests PASS"); } }