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

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: 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
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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read Target); 101 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read Target);
102 if (!readBuffer) 102 if (!readBuffer)
103 return; 103 return;
104 104
105 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri teTarget); 105 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri teTarget);
106 if (!writeBuffer) 106 if (!writeBuffer)
107 return; 107 return;
108 108
109 if (readOffset + size > readBuffer->getSize() || writeOffset + size > writeB uffer->getSize()) {
Zhenyao Mo 2015/09/02 17:59:03 Overflow detection. We made sure the offset/size f
yunchao 2015/09/04 08:22:07 the function validateValueFitNonNegInt32 makes sur
Zhenyao Mo 2015/09/04 18:36:28 Not really. Two uint32 adding won't overflow uint
110 synthesizeGLError(GL_INVALID_VALUE, "copyBufferSubData", "buffer overflo w");
111 return;
112 }
113
109 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER) 114 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER)
110 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) { 115 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
111 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop y into an element buffer destination from a non-element buffer source"); 116 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop y into an element buffer destination from a non-element buffer source");
112 return; 117 return;
113 } 118 }
114 119
115 if (writeBuffer->getInitialTarget() == 0) 120 if (writeBuffer->getInitialTarget() == 0)
116 writeBuffer->setInitialTarget(readBuffer->getInitialTarget()); 121 writeBuffer->setInitialTarget(readBuffer->getInitialTarget());
117 122
118 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size )); 123 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size ));
119 } 124 }
120 125
121 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse t, DOMArrayBuffer* returnedData) 126 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse t, DOMArrayBuffer* returnedData)
122 { 127 {
123 if (isContextLost()) 128 if (isContextLost())
124 return; 129 return;
125 130
126 if (!returnedData) { 131 if (!returnedData) {
127 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can not be null"); 132 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can not be null");
128 return; 133 return;
129 } 134 }
130 135
131 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) { 136 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) {
132 return; 137 return;
133 } 138 }
134 139
140 WebGLBuffer* buffer = validateBufferDataTarget("getBufferSubData", target);
141 if (!buffer)
142 return;
143 if (offset + returnedData->byteLength() > buffer->getSize()) {
Zhenyao Mo 2015/09/02 17:59:03 Same here. overflow detection.
yunchao 2015/09/04 08:22:07 same here.
144 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "buffer overflow ");
145 return;
146 }
147
135 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr >(offset), returnedData->byteLength(), GL_MAP_READ_BIT); 148 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr >(offset), returnedData->byteLength(), GL_MAP_READ_BIT);
136 149
137 if (!mappedData) 150 if (!mappedData)
138 return; 151 return;
139 152
140 memcpy(returnedData->data(), mappedData, returnedData->byteLength()); 153 memcpy(returnedData->data(), mappedData, returnedData->byteLength());
141 154
142 webContext()->unmapBuffer(target); 155 webContext()->unmapBuffer(target);
143 } 156 }
144 157
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 return false; 503 return false;
491 } 504 }
492 505
493 WebGLTexture* tex = validateTextureBinding(functionName, target, false); 506 WebGLTexture* tex = validateTextureBinding(functionName, target, false);
494 if (!tex) 507 if (!tex)
495 return false; 508 return false;
496 509
497 if (!validateTexFuncLevel(functionName, target, level)) 510 if (!validateTexFuncLevel(functionName, target, level))
498 return false; 511 return false;
499 512
500 if (width - xoffset > tex->getWidth(target, level) 513 if (width + xoffset > tex->getWidth(target, level)
Zhenyao Mo 2015/09/02 17:59:03 Same here, overflow detection.
yunchao 2015/09/04 08:22:07 Done.
501 || height - yoffset > tex->getHeight(target, level) 514 || height + yoffset > tex->getHeight(target, level)
502 || depth - zoffset > tex->getDepth(target, level)) { 515 || depth + zoffset > tex->getDepth(target, level)) {
503 synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range"); 516 synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of ran ge");
504 return false; 517 return false;
505 } 518 }
506 519
507 GLenum internalformat = tex->getInternalFormat(target, level); 520 GLenum internalformat = tex->getInternalFormat(target, level);
508 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type , level)) 521 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type , level))
509 return false; 522 return false;
510 523
511 return true; 524 return true;
512 } 525 }
513 526
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 } 603 }
591 if (m_unpackAlignment != 1) 604 if (m_unpackAlignment != 1)
592 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); 605 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
593 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels ->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix els->data()->data()); 606 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels ->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix els->data()->data());
594 if (m_unpackAlignment != 1) 607 if (m_unpackAlignment != 1)
595 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 608 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
596 } 609 }
597 610
598 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle ment* image, ExceptionState& exceptionState) 611 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle ment* image, ExceptionState& exceptionState)
599 { 612 {
600 if (isContextLost() || !image || !validateTexSubImage3D("texSubImage3D", tar get, level, xoffset, yoffset, zoffset, format, type, image->width(), image->heig ht(), 1)) 613 if (isContextLost() || !image || !validateHTMLImageElement("texSubImage3D", image, exceptionState))
601 return;
602
603 if (isContextLost() || !validateHTMLImageElement("texSubImage3D", image, exc eptionState))
604 return; 614 return;
605 615
606 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im age->layoutObject()); 616 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im age->layoutObject());
607 if (imageForRender->isSVGImage()) 617 if (imageForRender->isSVGImage())
608 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width( ), image->height(), "texSubImage3D"); 618 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width( ), image->height(), "texSubImage3D");
609 619
610 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP remultiplyAlpha); 620 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP remultiplyAlpha);
611 } 621 }
612 622
613 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl ement* canvas, ExceptionState& exceptionState) 623 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl ement* canvas, ExceptionState& exceptionState)
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 void WebGL2RenderingContextBase::bindBufferRange(GLenum target, GLuint index, We bGLBuffer* buffer, long long offset, long long size) 1666 void WebGL2RenderingContextBase::bindBufferRange(GLenum target, GLuint index, We bGLBuffer* buffer, long long offset, long long size)
1657 { 1667 {
1658 if (isContextLost() || !validateWebGLObject("bindBufferRange", buffer)) 1668 if (isContextLost() || !validateWebGLObject("bindBufferRange", buffer))
1659 return; 1669 return;
1660 1670
1661 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset) 1671 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset)
1662 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) { 1672 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) {
1663 return; 1673 return;
1664 } 1674 }
1665 1675
1676 if (buffer && (offset + size > buffer->getSize())) {
Zhenyao Mo 2015/09/02 17:59:03 Same here, overflow detection.
yunchao 2015/09/04 08:22:07 same here
1677 synthesizeGLError(GL_INVALID_VALUE, "bindBufferRange", "buffer overflow" );
1678 return;
1679 }
1680
1666 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca st<GLintptr>(offset), static_cast<GLsizeiptr>(size)); 1681 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca st<GLintptr>(offset), static_cast<GLsizeiptr>(size));
1667 } 1682 }
1668 1683
1669 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS tate, GLenum target, GLuint index) 1684 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS tate, GLenum target, GLuint index)
1670 { 1685 {
1671 if (isContextLost()) 1686 if (isContextLost())
1672 return ScriptValue::createNull(scriptState); 1687 return ScriptValue::createNull(scriptState);
1673 1688
1674 switch (target) { 1689 switch (target) {
1675 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 1690 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat() 2560 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat()
2546 { 2561 {
2547 if (m_readFramebufferBinding && m_readFramebufferBinding->object()) 2562 if (m_readFramebufferBinding && m_readFramebufferBinding->object())
2548 return m_readFramebufferBinding->colorBufferFormat(); 2563 return m_readFramebufferBinding->colorBufferFormat();
2549 if (m_requestedAttributes.alpha()) 2564 if (m_requestedAttributes.alpha())
2550 return GL_RGBA; 2565 return GL_RGBA;
2551 return GL_RGB; 2566 return GL_RGB;
2552 } 2567 }
2553 2568
2554 } // namespace blink 2569 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698