WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
239113
REGRESSION(
r249162
): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded
https://bugs.webkit.org/show_bug.cgi?id=239113
Summary
REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the...
Said Abou-Hallawa
Reported
2022-04-12 00:38:13 PDT
Some pages may draw the BitmapImage before loading the encoded data is complete. This case is already handled by BitmapImage::draw() which returns peacefully if the "current frame" cannot be decoded. To draw an animated BitmapImage to a canvas,
r249162
changed the old behavior to draw the first frame always. To do that, this revision creates another temporary static BitmapImage and draws this temporary BitmapImage instead of drawing the original image. This temporary static BitmapImage is created from the first frame of the original image. The problem is CanvasRenderingContext2DBase::drawImage() does not check whether the first frame is decoded with a valid NativeImage or not before creating the temporary static BitmapImage. If the NativeImage is null, BitmapImage will create an ImageSource with a null NativeImage. But because ImageSource does not take into account the case of the null NativeImage, a segmentation fault crash will happen once the members of the null NativeImage is accessed.
Attachments
Patch
(7.69 KB, patch)
2022-04-12 02:33 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(8.47 KB, patch)
2022-04-12 12:04 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(9.31 KB, patch)
2022-04-25 18:35 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(12.88 KB, patch)
2022-05-11 21:11 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(13.00 KB, patch)
2022-05-12 00:40 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Said Abou-Hallawa
Comment 1
2022-04-12 00:38:42 PDT
rdar://87980543
Said Abou-Hallawa
Comment 2
2022-04-12 02:33:30 PDT
Created
attachment 457318
[details]
Patch
Said Abou-Hallawa
Comment 3
2022-04-12 12:04:43 PDT
Created
attachment 457350
[details]
Patch
Simon Fraser (smfr)
Comment 4
2022-04-12 14:12:52 PDT
Comment on
attachment 457350
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=457350&action=review
> Source/WebCore/ChangeLog:11 > + static image. If the first frame can't be decoded, it should return
Do we know when this happens (when the first frame can't be decoded)?
Said Abou-Hallawa
Comment 5
2022-04-25 13:53:45 PDT
Comment on
attachment 457350
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=457350&action=review
>> Source/WebCore/ChangeLog:11 >> + static image. If the first frame can't be decoded, it should return > > Do we know when this happens (when the first frame can't be decoded)?
I think I misunderstood this bug. The null check will prevent the crash but it will leave a racy behavior while decoding the frames of the animated image. The problem is the animated image is decoded asynchronously. But drawing the animated image to the canvas requires decoding the first frame. So we decode the first frame synchronously. But ImageIO is not thread safe with regarding to the frame decoding. Also this will mess all ImageIO calculations since each frame is composed by adding a delta to the previous frame. ImageIO has to decode the frames 0, 1, ... n-1 to be able to decode frame n. So if we want to decode frame zero for canvas drawing while the current frame is n, ImageIO will delete all the frames and decode frame zero. Then it has to decode all the other frames from frame 1 till frame n-1 again before returning frame n. So it looks like we need to cache frame zero always and never delete it even under memory pressure. We use this rule with the current frame and we just need to extend to the frame zero as well.
Said Abou-Hallawa
Comment 6
2022-04-25 18:05:11 PDT
Comment on
attachment 457350
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=457350&action=review
>>> Source/WebCore/ChangeLog:11 >>> + static image. If the first frame can't be decoded, it should return >> >> Do we know when this happens (when the first frame can't be decoded)? > > I think I misunderstood this bug. The null check will prevent the crash but it will leave a racy behavior while decoding the frames of the animated image. > > The problem is the animated image is decoded asynchronously. But drawing the animated image to the canvas requires decoding the first frame. So we decode the first frame synchronously. But ImageIO is not thread safe with regarding to the frame decoding. Also this will mess all ImageIO calculations since each frame is composed by adding a delta to the previous frame. ImageIO has to decode the frames 0, 1, ... n-1 to be able to decode frame n. So if we want to decode frame zero for canvas drawing while the current frame is n, ImageIO will delete all the frames and decode frame zero. Then it has to decode all the other frames from frame 1 till frame n-1 again before returning frame n. > > So it looks like we need to cache frame zero always and never delete it even under memory pressure. We use this rule with the current frame and we just need to extend to the frame zero as well.
I tried to write a test case with multiple large animated images and I was hoping it will crash on macOS or on iOS but it did not. It looks like my theory about ImageIO being thread unsafe when decoding frames from different threads is incorrect.
Said Abou-Hallawa
Comment 7
2022-04-25 18:35:50 PDT
Created
attachment 458320
[details]
Patch
Said Abou-Hallawa
Comment 8
2022-05-11 21:11:05 PDT
Created
attachment 459207
[details]
Patch
Said Abou-Hallawa
Comment 9
2022-05-12 00:40:06 PDT
Created
attachment 459208
[details]
Patch
EWS
Comment 10
2022-05-16 16:46:10 PDT
Committed
r294280
(
250624@main
): <
https://commits.webkit.org/250624@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 459208
[details]
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug