diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-29 11:06:39 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-29 13:26:42 +0000 |
commit | ce4d3b4e0a6050a81fec26b85abb8f6b86198fb2 (patch) | |
tree | 4bfbdb243883a552d44db02cd32ae48bf6bcb6d2 | |
parent | cf3a94e300853fc3620d1ac73922232da14e5919 (diff) | |
download | qtwebengine-chromium-ce4d3b4e0a6050a81fec26b85abb8f6b86198fb2.tar.gz |
[Backport] Implement 2D texture uploading from client array with FLIP_Y or PREMULTIPLY_ALPHA.
BUG=774174
TEST=https://github.com/KhronosGroup/WebGL/pull/2555
R=kbr@chromium.org
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Reviewed-on: https://chromium-review.googlesource.com/808665
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#522003}(cherry picked from commit 9b99a43fc119a2533a87e2357cad8f603779a7b9)
Reviewed-on: https://chromium-review.googlesource.com/814698
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/branch-heads/3282@{#75}
Cr-Branched-From: 5fdc0fab22ce7efd32532ee989b223fa12f8171e-refs/heads/master@{#520840}
(CVE-2018-6038)
Change-Id: I01bd0d359c985f1148128d17ea593f5d32e05943
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
6 files changed, 101 insertions, 36 deletions
diff --git a/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp index ed81f39f6a4..2474fe5678f 100644 --- a/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp +++ b/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp @@ -1068,6 +1068,12 @@ void WebGL2RenderingContextBase::texImage2D(GLenum target, "no bound PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + SynthesizeGLError( + GL_INVALID_OPERATION, "texImage2D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed while uploading from PBO"); + return; + } if (!ValidateTexFunc("texImage2D", kTexImage, kSourceUnpackBuffer, target, level, internalformat, width, height, 1, border, format, type, 0, 0, 0)) @@ -1098,6 +1104,12 @@ void WebGL2RenderingContextBase::texSubImage2D(GLenum target, "no bound PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + SynthesizeGLError( + GL_INVALID_OPERATION, "texSubImage2D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed while uploading from PBO"); + return; + } if (!ValidateTexFunc("texSubImage2D", kTexSubImage, kSourceUnpackBuffer, target, level, 0, width, height, 1, 0, format, type, xoffset, yoffset, 0)) @@ -1679,6 +1691,12 @@ void WebGL2RenderingContextBase::texImage3D( GLenum format, GLenum type, MaybeShared<DOMArrayBufferView> pixels) { + if ((unpack_flip_y_ || unpack_premultiply_alpha_) && pixels) { + SynthesizeGLError( + GL_INVALID_OPERATION, "texImage3D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed for uploading 3D textures"); + return; + } TexImageHelperDOMArrayBufferView(kTexImage3D, target, level, internalformat, width, height, depth, border, format, type, 0, 0, 0, pixels.View(), kNullAllowed, 0); @@ -1703,6 +1721,13 @@ void WebGL2RenderingContextBase::texImage3D( "a buffer is bound to PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + DCHECK(pixels); + SynthesizeGLError( + GL_INVALID_OPERATION, "texImage3D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed for uploading 3D textures"); + return; + } TexImageHelperDOMArrayBufferView( kTexImage3D, target, level, internalformat, width, height, depth, border, format, type, 0, 0, 0, pixels.View(), kNullNotReachable, src_offset); @@ -1727,6 +1752,12 @@ void WebGL2RenderingContextBase::texImage3D(GLenum target, "no bound PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + SynthesizeGLError( + GL_INVALID_OPERATION, "texImage3D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed for uploading 3D textures"); + return; + } if (!ValidateTexFunc("texImage3D", kTexImage, kSourceUnpackBuffer, target, level, internalformat, width, height, depth, border, format, type, 0, 0, 0)) @@ -1885,6 +1916,14 @@ void WebGL2RenderingContextBase::texSubImage3D( "a buffer is bound to PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + DCHECK(pixels); + SynthesizeGLError( + GL_INVALID_OPERATION, "texSubImage3D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed for uploading 3D textures"); + return; + } + TexImageHelperDOMArrayBufferView( kTexSubImage3D, target, level, 0, width, height, depth, 0, format, type, xoffset, yoffset, zoffset, pixels.View(), kNullNotReachable, src_offset); @@ -1910,6 +1949,12 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, "no bound PIXEL_UNPACK_BUFFER"); return; } + if (unpack_flip_y_ || unpack_premultiply_alpha_) { + SynthesizeGLError( + GL_INVALID_OPERATION, "texSubImage3D", + "FLIP_Y or PREMULTIPLY_ALPHA isn't allowed for uploading 3D textures"); + return; + } if (!ValidateTexFunc("texSubImage3D", kTexSubImage, kSourceUnpackBuffer, target, level, 0, width, height, depth, 0, format, type, xoffset, yoffset, zoffset)) diff --git a/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h index 90b74986ffd..0e31b3f5167 100644 --- a/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h +++ b/chromium/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h @@ -1133,10 +1133,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase { GLint pack_row_length_; GLint pack_skip_pixels_; GLint pack_skip_rows_; - GLint unpack_row_length_; GLint unpack_image_height_; - GLint unpack_skip_pixels_; - GLint unpack_skip_rows_; GLint unpack_skip_images_; HeapHashSet<Member<WebGLGetBufferSubDataAsyncCallback>> diff --git a/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index a025578e8cf..db33e27ad97 100644 --- a/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp @@ -4635,22 +4635,31 @@ void WebGLRenderingContextBase::TexImageHelperDOMArrayBufferView( data += src_offset * pixels->TypeSize(); } Vector<uint8_t> temp_data; - bool change_unpack_alignment = false; - if (data && (unpack_flip_y_ || unpack_premultiply_alpha_)) { - if (source_type == kTex2D) { - if (!WebGLImageConversion::ExtractTextureData( - width, height, format, type, unpack_alignment_, unpack_flip_y_, - unpack_premultiply_alpha_, data, temp_data)) { - SynthesizeGLError(GL_INVALID_OPERATION, func_name, - "Invalid format/type combination."); - return; - } - data = temp_data.data(); + bool change_unpack_params = false; + if (data && width && height && + (unpack_flip_y_ || unpack_premultiply_alpha_)) { + DCHECK_EQ(kTex2D, source_type); + // Only enter here if width or height is non-zero. Otherwise, call to the + // underlying driver to generate appropriate GL errors if needed. + WebGLImageConversion::PixelStoreParams unpack_params = + GetUnpackPixelStoreParams(kTex2D); + GLint data_store_width = + unpack_params.row_length ? unpack_params.row_length : width; + if (unpack_params.skip_pixels + width > data_store_width) { + SynthesizeGLError(GL_INVALID_OPERATION, func_name, + "Invalid unpack params combination."); + return; + } + if (!WebGLImageConversion::ExtractTextureData( + width, height, format, type, unpack_params, unpack_flip_y_, + unpack_premultiply_alpha_, data, temp_data)) { + SynthesizeGLError(GL_INVALID_OPERATION, func_name, + "Invalid format/type combination."); + return; } - change_unpack_alignment = true; + data = temp_data.data(); + change_unpack_params = true; } - // TODO(crbug.com/666064): implement flipY and premultiplyAlpha for - // tex(Sub)3D. if (function_id == kTexImage3D) { ContextGL()->TexImage3D(target, level, ConvertTexInternalFormat(internalformat, type), @@ -4664,7 +4673,7 @@ void WebGLRenderingContextBase::TexImageHelperDOMArrayBufferView( } ScopedUnpackParametersResetRestore temporary_reset_unpack( - this, change_unpack_alignment); + this, change_unpack_params); if (function_id == kTexImage2D) TexImage2DBase(target, level, internalformat, width, height, border, format, type, data); diff --git a/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 98242f5e0ca..0091b3faec3 100644 --- a/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/chromium/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h @@ -759,11 +759,15 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, GLenum read_buffer_of_default_framebuffer_; - GLint pack_alignment_; - GLint unpack_alignment_; - bool unpack_flip_y_; - bool unpack_premultiply_alpha_; - GLenum unpack_colorspace_conversion_; + GLint pack_alignment_ = 4; + GLint unpack_alignment_ = 4; + bool unpack_flip_y_ = false; + bool unpack_premultiply_alpha_ = false; + GLenum unpack_colorspace_conversion_ = GC3D_BROWSER_DEFAULT_WEBGL; + // The following three unpack params belong to WebGL2 only. + GLint unpack_skip_pixels_ = 0; + GLint unpack_skip_rows_ = 0; + GLint unpack_row_length_ = 0; GLfloat clear_color_[4]; bool scissor_enabled_; diff --git a/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp b/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp index b4736e483e2..cf00d5c214d 100644 --- a/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp +++ b/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp @@ -3025,15 +3025,16 @@ bool WebGLImageConversion::ExtractImageData( return true; } -bool WebGLImageConversion::ExtractTextureData(unsigned width, - unsigned height, - GLenum format, - GLenum type, - unsigned unpack_alignment, - bool flip_y, - bool premultiply_alpha, - const void* pixels, - Vector<uint8_t>& data) { +bool WebGLImageConversion::ExtractTextureData( + unsigned width, + unsigned height, + GLenum format, + GLenum type, + const PixelStoreParams& unpack_params, + bool flip_y, + bool premultiply_alpha, + const void* pixels, + Vector<uint8_t>& data) { // Assumes format, type, etc. have already been validated. DataFormat source_data_format = GetDataFormat(format, type); if (source_data_format == kDataFormatNumFormats) @@ -3047,9 +3048,18 @@ bool WebGLImageConversion::ExtractTextureData(unsigned width, unsigned bytes_per_pixel = components_per_pixel * bytes_per_component; data.resize(width * height * bytes_per_pixel); - if (!PackPixels(static_cast<const uint8_t*>(pixels), source_data_format, - width, height, IntRect(0, 0, width, height), 1, - unpack_alignment, 0, format, type, + unsigned image_size_in_bytes, skip_size_in_bytes; + ComputeImageSizeInBytes(format, type, width, height, 1, unpack_params, + &image_size_in_bytes, nullptr, &skip_size_in_bytes); + const uint8_t* src_data = static_cast<const uint8_t*>(pixels); + if (skip_size_in_bytes) { + src_data += skip_size_in_bytes; + } + + if (!PackPixels(src_data, source_data_format, + unpack_params.row_length ? unpack_params.row_length : width, + height, IntRect(0, 0, width, height), 1, + unpack_params.alignment, 0, format, type, (premultiply_alpha ? kAlphaDoPremultiply : kAlphaDoNothing), data.data(), flip_y)) return false; diff --git a/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h b/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h index 4fbb671b7f8..ff2b837c665 100644 --- a/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h +++ b/chromium/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h @@ -249,7 +249,7 @@ class PLATFORM_EXPORT WebGLImageConversion final { unsigned height, GLenum format, GLenum type, - unsigned unpack_alignment, + const PixelStoreParams& unpack_params, bool flip_y, bool premultiply_alpha, const void* pixels, |