Skip to content

[Bug] Invalid handling bufferSubData after grown source array size #27180

@eXponenta

Description

@eXponenta

Description

Sometimes we require use a dynamic size of buffer data, but three not allow use it, because use a bufferSubData without checking a reference size, and we down by "Buffer Overflow"

Bug located in updateBuffer method:

gl.bufferSubData( bufferType, 0, array );

On this line three should check a source array size and throw error or call bufferData if source array greater than was before.

We easy can store creating size inside a metadata.

Reproduction steps

  1. Create a new BufferGeometry
  2. Bind a attribute with specific size
  3. Conditionally try update attribute source data onto array that greater than was before on this attribute.
  4. Get a "WebGL: INVALID_VALUE: bufferSubData: buffer overflow"
  5. Cry!!

Code

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000 );
const renderer = new THREE.WebGLRenderer({ antialias: true });

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xaaaaaa, 1);
document.body.appendChild(renderer.domElement);

const vertices = new Float32Array([
	-1.0, -1.0, 1.0, // v0
	1.0, -1.0, 1.0, // v1
	1.0, 1.0, 1.0, // v2
]);

const geometry = new THREE.BufferGeometry();

geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));

const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);
camera.position.z = 5;

function render() {
	renderer.render(scene, camera);
	requestAnimationFrame(render);
}
render();

/** --------------------------- LOOKS TO THIS ----------------------- */
document.addEventListener('DOMContentLoaded', () => {
	document.querySelector("#updateBuffer").addEventListener("click", () => {
	
		const attr = geometry.getAttribute("position");

		// try update buffer data with overflow
		attr.array = new Float32Array([
				-1.0, -1.0, 1.0, // v0
				1.0, -1.0, 1.0, // v1
				1.0, 1.0, 1.0, // v2
				
				 1.0,  1.0,  1.0, // v3
				-1.0,  1.0,  1.0, // v4
				-1.0, -1.0,  1.0  // v5
		]);
	
		attr.needsUpdate = true;
	});
});

Live example

Replit demo:

Screenshots

Снимок экрана 2023-11-13 в 12 58 48

Version

any

Device

Desktop, Mobile, Headset

Browser

Chrome, Firefox, Safari, Edge

OS

Windows, MacOS, Linux, ChromeOS, Android

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions