Page MenuHome

Crash when creating meshes with negative indices
Closed, InvalidPublic

Description

System Information
Tested on
Ubuntu 14.04 (64), GT 730M
and Windows 7 (64), GTX 580

Blender Version
Broken: 2.76b

Steps to reproduce:
1 - Run this code in the text editor

import bpy

verts = ((0.0, 0.0, 0.0),
         (-1.0, 0.0, 0.0),
         (-1.0, 1.0, 0.0))

indices = ((-1, 1, 2),)

mesh = bpy.data.meshes.new('test')
mesh.from_pydata(verts, (), indices)

Observed behavior
Blender crashes

Expected behavior
Exception at Python level

Event Timeline

Sebastian Brachi (brachi) raised the priority of this task from to 90.
Sebastian Brachi (brachi) updated the task description. (Show Details)
Sebastian Brachi (brachi) edited a custom field.

Creating a mesh with indices outside of the vertices bounds also crash blender. Going into edit mode might be necessary.
This can actually be prevented with mesh.validate()

import bpy

verts = ((0.0, 0.0, 0.0),
         (-1.0, 0.0, 0.0),
         (-1.0, 1.0, 0.0))

indices = ((1000, 34, 234),)

mesh = bpy.data.meshes.new('test')
mesh.from_pydata(verts, (), indices)

ob = bpy.data.objects.new('test', mesh)
bpy.context.scene.objects.link(ob)
Bastien Montagne (mont29) changed the task status from Unknown Status to Invalid.Dec 28 2015, 9:58 AM
Bastien Montagne (mont29) claimed this task.

Well, if you want to try crazy things, it’s your problem, but do not expect Blender to check all and every possible mistake you can make using its python “API”… Crashing it like that is very, very easy, and doable in a rather fancy number of different ways. If you want to write code, you have to write valid code, no bug here.

Hi Bastien,
While I agree that it might not feasible or useful to catch all inputs and cases functions from the API can crash Blender[1], this specific function, from_pydata, should be a little more 'robust' IMHO since it's used by importers a lot. A simple mistake like struct.unpack('h') instead of 'H', could go unnoticed for a long time. In my case was a bug in a function that was converting strip indices to list indices, and I could only found it after testing hundreds of models.
A quick dirty way to avoid this at the Python level would be to add 'assert min(faces) > 0' in Mesh.from_pydata. What do you think?
I looked at bpy_rna.c, but it doesn't seem so straightforward to fix at that level.

[1] Ideally, unit tests with different inputs should be added to as many functions as possible, to at least have a knowledge of all the different ways to crash Blender. I'd like to do that at some point.

As you found it yourself, that’s what mesh.validate(True) is made for. If you have a look at our 'official' importers, you'll see they use it too - because even when importer code is correct, there are still some invalid/corrupted files around…

The point is you can't use mesh.validate() or a try/except because Blender crashes before you arrive there.