diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-09-22 13:42:02 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-09-23 08:46:10 +0200 |
commit | 797315f220f82682748efaf80a29844a93f04f48 (patch) | |
tree | f11129728fd9bd046a9d1a3ce120797180809495 /vcl/skia/SkiaHelper.cxx | |
parent | 19365e6e2b3311bacb2ae2abb70be5cfaf843776 (diff) |
detect and fail immediately on failed Skia allocations (tdf#135952)
The problem with tdf#135952 is that the PNG export dialog can lead
to requesting an absurdly large image, which leads to allocation
failures. Some VCL backends such as headless try to cope with this
and bail out, but they often crash anyway, since at higher levels
of LO code nothing checks for these corner cases anyway. And even
if nothing would crash, this can lead to silently losing data.
So I've decided to directly detect such cases and fail hard and early.
Change-Id: I5277a65c794116206de8280faf22ff897daa2f56
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103171
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/skia/SkiaHelper.cxx')
-rw-r--r-- | vcl/skia/SkiaHelper.cxx | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx index e029a9137429..f9b231d87ce6 100644 --- a/vcl/skia/SkiaHelper.cxx +++ b/vcl/skia/SkiaHelper.cxx @@ -413,10 +413,16 @@ sk_sp<SkSurface> createSkSurface(int width, int height, SkColorType type) // Create raster surface as a fallback. surface = SkSurface::MakeRaster(SkImageInfo::Make(width, height, type, kPremul_SkAlphaType)); assert(surface); + if (surface) + { #ifdef DBG_UTIL - prefillSurface(surface); + prefillSurface(surface); #endif - return surface; + return surface; + } + // In non-debug builds we could return SkSurface::MakeNull() and try to cope with the situation, + // but that can lead to unnoticed data loss, so better fail clearly. + abort(); } sk_sp<SkImage> createSkImage(const SkBitmap& bitmap) @@ -437,7 +443,7 @@ sk_sp<SkImage> createSkImage(const SkBitmap& bitmap) SkPaint paint; paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha surface->getCanvas()->drawBitmap(bitmap, 0, 0, &paint); - return surface->makeImageSnapshot(); + return makeCheckedImageSnapshot(surface); } // Try to fall back in non-debug builds. SAL_WARN("vcl.skia", @@ -454,6 +460,24 @@ sk_sp<SkImage> createSkImage(const SkBitmap& bitmap) return image; } +sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface) +{ + sk_sp<SkImage> ret = surface->makeImageSnapshot(); + assert(ret); + if (ret) + return ret; + abort(); +} + +sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface, const SkIRect& bounds) +{ + sk_sp<SkImage> ret = surface->makeImageSnapshot(bounds); + assert(ret); + if (ret) + return ret; + abort(); +} + namespace { // Image cache, for saving results of complex operations such as drawTransformedBitmap(). @@ -573,7 +597,7 @@ void dump(const SkBitmap& bitmap, const char* file) { dump(SkImage::MakeFromBitm void dump(const sk_sp<SkSurface>& surface, const char* file) { surface->getCanvas()->flush(); - dump(surface->makeImageSnapshot(), file); + dump(makeCheckedImageSnapshot(surface), file); } void dump(const sk_sp<SkImage>& image, const char* file) |