Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: Source/modules/webgl/WebGL2RenderingContextBase.cpp

Issue 1315983010: WebGL: validations and fixes to avoid buffer/texture overflow (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: code rebase Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "modules/webgl/WebGL2RenderingContextBase.h" 6 #include "modules/webgl/WebGL2RenderingContextBase.h"
7 7
8 #include "bindings/modules/v8/WebGLAny.h" 8 #include "bindings/modules/v8/WebGLAny.h"
9 #include "core/html/HTMLCanvasElement.h" 9 #include "core/html/HTMLCanvasElement.h"
10 #include "core/html/HTMLImageElement.h" 10 #include "core/html/HTMLImageElement.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 111 }
112 112
113 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read Target); 113 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read Target);
114 if (!readBuffer) 114 if (!readBuffer)
115 return; 115 return;
116 116
117 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri teTarget); 117 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri teTarget);
118 if (!writeBuffer) 118 if (!writeBuffer)
119 return; 119 return;
120 120
121 if (readOffset + size > readBuffer->getSize() || writeOffset + size > writeB uffer->getSize()) {
122 synthesizeGLError(GL_INVALID_VALUE, "copyBufferSubData", "buffer overflo w");
123 return;
124 }
125
121 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER) 126 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER)
122 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) { 127 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
123 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop y into an element buffer destination from a non-element buffer source"); 128 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop y into an element buffer destination from a non-element buffer source");
124 return; 129 return;
125 } 130 }
126 131
127 if (writeBuffer->getInitialTarget() == 0) 132 if (writeBuffer->getInitialTarget() == 0)
128 writeBuffer->setInitialTarget(readBuffer->getInitialTarget()); 133 writeBuffer->setInitialTarget(readBuffer->getInitialTarget());
129 134
130 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size )); 135 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size ));
131 } 136 }
132 137
133 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse t, DOMArrayBuffer* returnedData) 138 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse t, DOMArrayBuffer* returnedData)
134 { 139 {
135 if (isContextLost()) 140 if (isContextLost())
136 return; 141 return;
137 142
138 if (!returnedData) { 143 if (!returnedData) {
139 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can not be null"); 144 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can not be null");
140 return; 145 return;
141 } 146 }
142 147
143 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) { 148 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) {
144 return; 149 return;
145 } 150 }
146 151
152 WebGLBuffer* buffer = validateBufferDataTarget("getBufferSubData", target);
153 if (!buffer)
154 return;
155 if (offset + returnedData->byteLength() > buffer->getSize()) {
156 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "buffer overflow ");
157 return;
158 }
159
147 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr >(offset), returnedData->byteLength(), GL_MAP_READ_BIT); 160 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr >(offset), returnedData->byteLength(), GL_MAP_READ_BIT);
148 161
149 if (!mappedData) 162 if (!mappedData)
150 return; 163 return;
151 164
152 memcpy(returnedData->data(), mappedData, returnedData->byteLength()); 165 memcpy(returnedData->data(), mappedData, returnedData->byteLength());
153 166
154 webContext()->unmapBuffer(target); 167 webContext()->unmapBuffer(target);
155 } 168 }
156 169
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 return false; 515 return false;
503 } 516 }
504 517
505 WebGLTexture* tex = validateTextureBinding(functionName, target, false); 518 WebGLTexture* tex = validateTextureBinding(functionName, target, false);
506 if (!tex) 519 if (!tex)
507 return false; 520 return false;
508 521
509 if (!validateTexFuncLevel(functionName, target, level)) 522 if (!validateTexFuncLevel(functionName, target, level))
510 return false; 523 return false;
511 524
512 if (width - xoffset > tex->getWidth(target, level) 525 // Before checking if it is in the range, check if overflow happens first.
513 || height - yoffset > tex->getHeight(target, level) 526 Checked<GLint, RecordOverflow> maxX = xoffset, maxY = yoffset, maxZ = zoffse t;
514 || depth - zoffset > tex->getDepth(target, level)) { 527 maxX += width;
515 synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range"); 528 maxY += height;
529 maxZ += depth;
530 if (maxX.hasOverflowed() || maxY.hasOverflowed() || maxZ.hasOverflowed()
531 || maxX.unsafeGet() > tex->getWidth(target, level)
532 || maxY.unsafeGet() > tex->getHeight(target, level)
533 || maxZ.unsafeGet() > tex->getDepth(target, level)) {
534 synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of ran ge");
516 return false; 535 return false;
517 } 536 }
518 537
519 GLenum internalformat = tex->getInternalFormat(target, level); 538 GLenum internalformat = tex->getInternalFormat(target, level);
520 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type , level)) 539 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type , level))
521 return false; 540 return false;
522 541
523 return true; 542 return true;
524 } 543 }
525 544
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 621 }
603 if (m_unpackAlignment != 1) 622 if (m_unpackAlignment != 1)
604 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); 623 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
605 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels ->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix els->data()->data()); 624 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels ->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix els->data()->data());
606 if (m_unpackAlignment != 1) 625 if (m_unpackAlignment != 1)
607 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 626 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
608 } 627 }
609 628
610 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle ment* image, ExceptionState& exceptionState) 629 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle ment* image, ExceptionState& exceptionState)
611 { 630 {
612 if (isContextLost() || !image || !validateTexSubImage3D("texSubImage3D", tar get, level, xoffset, yoffset, zoffset, format, type, image->width(), image->heig ht(), 1)) 631 if (isContextLost() || !image || !validateHTMLImageElement("texSubImage3D", image, exceptionState))
613 return;
614
615 if (isContextLost() || !validateHTMLImageElement("texSubImage3D", image, exc eptionState))
616 return; 632 return;
617 633
618 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im age->layoutObject()); 634 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im age->layoutObject());
619 if (imageForRender->isSVGImage()) 635 if (imageForRender->isSVGImage())
620 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width( ), image->height(), "texSubImage3D"); 636 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width( ), image->height(), "texSubImage3D");
621 637
622 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP remultiplyAlpha); 638 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP remultiplyAlpha);
623 } 639 }
624 640
625 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl ement* canvas, ExceptionState& exceptionState) 641 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl ement* canvas, ExceptionState& exceptionState)
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 bool deleted; 1690 bool deleted;
1675 if (!checkObjectToBeBound("bindBufferRange", buffer, deleted)) 1691 if (!checkObjectToBeBound("bindBufferRange", buffer, deleted))
1676 return; 1692 return;
1677 if (deleted) 1693 if (deleted)
1678 buffer = 0; 1694 buffer = 0;
1679 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset) 1695 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset)
1680 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) { 1696 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) {
1681 return; 1697 return;
1682 } 1698 }
1683 1699
1684 if (!validateAndUpdateBufferBindBaseTarget("bindBufferRange", target, index, buffer)) 1700 if (buffer && (offset + size > buffer->getSize())) {
1701 synthesizeGLError(GL_INVALID_VALUE, "bindBufferRange", "buffer overflow" );
1685 return; 1702 return;
1703 }
1686 1704
1687 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca st<GLintptr>(offset), static_cast<GLsizeiptr>(size)); 1705 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca st<GLintptr>(offset), static_cast<GLsizeiptr>(size));
1688 } 1706 }
1689 1707
1690 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS tate, GLenum target, GLuint index) 1708 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS tate, GLenum target, GLuint index)
1691 { 1709 {
1692 if (isContextLost()) 1710 if (isContextLost())
1693 return ScriptValue::createNull(scriptState); 1711 return ScriptValue::createNull(scriptState);
1694 1712
1695 switch (target) { 1713 switch (target) {
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
2723 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat() 2741 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat()
2724 { 2742 {
2725 if (m_readFramebufferBinding && m_readFramebufferBinding->object()) 2743 if (m_readFramebufferBinding && m_readFramebufferBinding->object())
2726 return m_readFramebufferBinding->colorBufferFormat(); 2744 return m_readFramebufferBinding->colorBufferFormat();
2727 if (m_requestedAttributes.alpha()) 2745 if (m_requestedAttributes.alpha())
2728 return GL_RGBA; 2746 return GL_RGBA;
2729 return GL_RGB; 2747 return GL_RGB;
2730 } 2748 }
2731 2749
2732 } // namespace blink 2750 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698