fix(🎨): fix crashes and dropped arguments in SkCanvas methods (#4062) - #4063
Pcmhacker-piro wants to merge 7 commits into
Conversation
…y#4062) - Guard drawPatch against out-of-bounds access and null dereference on paint - Guard drawPatch blendMode and provide default based on colors presence - Fix drawAtlas blendMode argument count check from count > 5 to count >= 5 - Allow paint to be optional/null in drawImage, drawImageRect, and saveLayer - Allow empty points array in drawPoints without throwing - Provide fallback Paint on Web for drawPatch and drawImageRect - Add unit and e2e tests covering all cases
be3f74c to
0d8233e
Compare
|
I have signed the CLA! |
|
Hi @wcandillon, @chrfalch 👋 Could you please take a look at this PR when you get a chance? Quick Context:This PR resolves #4062 by addressing parameter crashes and dropped arguments across
The Shopify CLA has been signed, and a terminal demo GIF along with verification screenshots are embedded in the PR description for easy review. Looking forward to your feedback and happy to make any adjustments! Thank you for your time. |
… Hermes ReferenceError
|
Thanks @wcandillon for adding the snapshot tests and the I noticed the CI runs ( Cause & Fix:In remote e2e execution ( In commit f18a9aa, I updated All unit and e2e tests pass cleanly locally ( |
What does this PR do?
This PR resolves several critical crash bugs, null pointer dereferences, and dropped optional arguments across
SkCanvasJSI C++, Web CanvasKit (JsiSkCanvas.ts), and TypeScript declarations.Specifically:
drawPatchCrash & Default BlendMode: In the native C++ layer,arguments[4](paint) was accessed whencount >= 4instead ofcount >= 5, causing an out-of-bounds array access on the JSI argument list and a hard null pointer dereference (*paint) wheneverpaintwas omitted or passed asnull. Additionally,drawPatchblend mode defaults toSkBlendMode::kModulatewhen omitted (matching Web CanvasKit). On Web CanvasKit,withPaintsafely manages temporary fallbackPaintallocation and cleanup without leaking on the WASM heap.drawAtlasDropped Argument: Passing 5 arguments todrawAtlas(e.g.canvas.drawAtlas(image, sprites, transforms, paint, blendMode)) silently droppedblendModewhencolorswas omitted because the argument check was strictlycount > 5.drawImageanddrawImageRectType Inconsistency & Crashes: The TypeScript interface markedpaintas required or non-nullable, but CanvasKit threw when null was passed.saveLayerNull Dereference & Bounds Handling: Passingnullfor the paint argument resulted in an unguarded dereference. Plain-object bounds{ x, y, width, height }are properly accepted.drawPointsInconsistent Exception: Passing an empty points array ([]) threw an unexpectedstd::invalid_argumentinstead of safely no-opping like Skia core.Fixes: #4062
Changes proposed in this pull request:
Native C++ JSI Layer (
packages/skia/cpp/api/JsiSkCanvas.h)drawPatchGuard & Fallback: Guardedpaintargument withcount >= 5 && !arguments[4].isNull() && !arguments[4].isUndefined(). Provided a stack-allocated fallbackSkPaint defaultPaintto prevent null pointer dereferences whenpaintis omitted. Default blend mode resolves toSkBlendMode::kModulatewhen omitted.drawAtlasArgument Count Fix: Updated theblendModecheck fromcount > 5tocount >= 5 && !arguments[4].isNull() && !arguments[4].isUndefined()so callers omittingcolorsretain their customblendMode. Added null guards forcolorsandsampling.drawImage&drawImageRectNull/Undefined Guards: Addedcount >= 4 && !arguments[3].isNull() && !arguments[3].isUndefined()guards before parsing paint.saveLayerGuard: Added!arguments[0].isNull()check to avoid dereferencing null paints.drawPointsEarly Return: Replaced throwingstd::invalid_argumentwith an early return (if (points.empty()) return;).Web CanvasKit Layer (
packages/skia/src/skia/web/JsiSkCanvas.ts)withPaint): Wrapped paint usage inwithPaint(paint, draw)to safely allocate a temporary fallback CanvasKitPaintand delete it in afinallyblock to prevent leaks on the WASM heap whenpaintis null or omitted.drawPointsEarly Return: Addedif (points.length === 0) return;to cleanly no-op on empty point arrays.TypeScript Definitions (
packages/skia/src/skia/types/Canvas.ts)paint?: SkPaint | nullacrossdrawImage,drawImageRect,drawPatch, andsaveLayer.Automated Unit & E2E Tests
packages/skia/src/skia/__tests__/ZeroValues.spec.ts: Added unit tests verifyingdrawAtlas,drawPatch, anddrawPointswith omitted/zero arguments.packages/skia/src/renderer/__tests__/e2e/Canvas.spec.ts: Added comprehensive end-to-end offscreen snapshot tests verifying all canvas methods against live surfaces and matching CanvasKit defaults. Passed enums viactxto ensure compatibility with remote deviceevalon Hermes.How to test this:
yarn --cwd packages/skia test ZeroValues.spec.ts Canvas.spec.ts --verboseyarn test