Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 9197450e126a7cb9906153e40ad0c97e731fec73
      
https://github.com/WebKit/WebKit/commit/9197450e126a7cb9906153e40ad0c97e731fec73
  Author: Mike Wyrzykowski <[email protected]>
  Date:   2026-10-13 (Tue, 13 Oct 2026)

  Changed paths:
    A 
LayoutTests/fast/webgpu/copy-external-image-video-frame-odd-width-expected.txt
    A LayoutTests/fast/webgpu/copy-external-image-video-frame-odd-width.html
    A LayoutTests/fast/webgpu/copy-image-non-bitmap-source-expected.txt
    A LayoutTests/fast/webgpu/copy-image-non-bitmap-source.html
    M Source/WebCore/Modules/WebGPU/GPUQueue.cpp

  Log Message:
  -----------
  MallocSpan crash in GPUQueue::copyExternalImageToTexture
https://bugs.webkit.org/show_bug.cgi?id=324153
rdar://187345349

Reviewed by Dan Glastonbury.

copyExternalImageToTexture()'s CPU readback path trusted what CGImage reported
about a decoded image, and trusted that an <img> holds either a BitmapImage or
an SVGImage. Neither holds, which left the path with an out of bounds read, a
null dereference, and a few smaller defects. Each is fixed here:

- clipTo8bitsPerChannel() left byteSpanBacking untouched for a bits per
  component it did not know how to narrow, and the caller used it anyway.
  The span was empty, so bytesPerPixel came out zero, maxChannelIndex
  underflowed to SIZE_MAX, and the pixel loop read past the end of the
  buffer. It returns false now, and the copy is rejected.

- An <img> can also hold a PDFDocumentImage, which is neither a BitmapImage
  nor an SVGImage. dynamicDowncast<SVGImage>() returned null for one and the
  result was dereferenced unconditionally. Only an SVGImage takes that branch
  now; a PDFDocumentImage has no pixels of its own to copy, so the copy is
  rejected.

- The pixel loop's reads are bounded against the length of the data the
  provider actually returned, rather than against the CGImage metadata, which
  is not guaranteed to agree with it. The sizes are computed with CheckedSize,
  so an implausible width or height cannot wrap.

- bytesPerPixel is the channel count, from CGImageGetBitsPerPixel() over
  CGImageGetBitsPerComponent(), rather than the decoded size divided by the
  pixel count. The latter folded end of row padding into it, which both
  overstated the pixel size and misplaced every channel read: an 8x8
  grayscale image whose rows were padded to 32 bytes looked like it had 4
  bytes per pixel. That image also satisfied the fast path, which handed the
  gray bytes over as though they were RGBA, so the fast path now requires 4
  bytes per pixel and rows without padding.

- CGImageGetAlphaInfo() is not guaranteed to return one of the enumerators
  the channel mapping switches over, so the lambda could fall off the end.
  It returns a default now.

- The orientation is read from the CachedImage already fetched above and
  tolerates it having no image, rather than going back through the element.

- The video frame path gets the same length check. On top of that,
  vImagePermuteChannels_ARGB8888() touches width * 4 bytes of every row, so
  the image is required here to be 32 bits per pixel with a stride at least
  that wide, instead of inheriting that from the conformer in the GPU process
  several layers up; and the stride CoreGraphics reports is what rowBytes is
  set to, rather than the data length divided by the height, so a frame whose
  rows CoreVideo padded is walked correctly.

Tests: fast/webgpu/copy-external-image-video-frame-odd-width.html
       fast/webgpu/copy-image-non-bitmap-source.html

* 
LayoutTests/fast/webgpu/copy-external-image-video-frame-odd-width-expected.txt: 
Added.
* LayoutTests/fast/webgpu/copy-external-image-video-frame-odd-width.html: Added.
* LayoutTests/fast/webgpu/copy-image-non-bitmap-source-expected.txt: Added.
* LayoutTests/fast/webgpu/copy-image-non-bitmap-source.html: Added.
* Source/WebCore/Modules/WebGPU/GPUQueue.cpp:
(WebCore::getImageBytesFromVideoFrame):
(WebCore::clipTo8bitsPerChannel):
(WebCore::imageBytesForSource):

Canonical link: https://commits.webkit.org/323636@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to