From 878a739f3c3b516b0c5d08389c40a685aa4ab5ea Mon Sep 17 00:00:00 2001 From: Bastien Montagne <montagne29@wanadoo.fr> Date: Sat, 8 Sep 2012 09:15:52 +0000 Subject: [PATCH] Fix [#32511] blender hangs on importing malformed ply file Made a few refactoring/style cleanup of code here... --- io_mesh_ply/import_ply.py | 112 +++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/io_mesh_ply/import_ply.py b/io_mesh_ply/import_ply.py index f5c96d7bf..6c80a3900 100644 --- a/io_mesh_ply/import_ply.py +++ b/io_mesh_ply/import_ply.py @@ -148,68 +148,64 @@ def read(filepath): b'double': 'd', b'string': 's'} obj_spec = object_spec() + invalid_ply = (None, None, None) - file = open(filepath, 'rb') # Only for parsing the header, not binary data - signature = file.readline() + with open(filepath, 'rb') as plyf: + signature = plyf.readline() - if not signature.startswith(b'ply'): - print('Signature line was invalid') - return None + if not signature.startswith(b'ply'): + print('Signature line was invalid') + return invalid_ply - while 1: - tokens = re.split(br'[ \r\n]+', file.readline()) + valid_header = False + for line in plyf: + tokens = re.split(br'[ \r\n]+', line) - if len(tokens) == 0: - continue - if tokens[0] == b'end_header': - break - elif tokens[0] == b'comment': - if len(tokens) < 2: + if len(tokens) == 0: continue - elif tokens[1] == b'TextureFile': - if len(tokens) < 4: - print('Invalid texture line') + if tokens[0] == b'end_header': + valid_header = True + break + elif tokens[0] == b'comment': + if len(tokens) < 2: + continue + elif tokens[1] == b'TextureFile': + if len(tokens) < 4: + print('Invalid texture line') + else: + texture = tokens[2] + continue + elif tokens[0] == b'obj_info': + continue + elif tokens[0] == b'format': + if len(tokens) < 3: + print('Invalid format line') + return invalid_ply + if tokens[1] not in format_specs: + print('Unknown format', tokens[1]) + return invalid_ply + if tokens[2] != version: + print('Unknown version', tokens[2]) + return invalid_ply + format = tokens[1] + elif tokens[0] == b'element': + if len(tokens) < 3: + print(b'Invalid element line') + return invalid_ply + obj_spec.specs.append(element_spec(tokens[1], int(tokens[2]))) + elif tokens[0] == b'property': + if not len(obj_spec.specs): + print('Property without element') + return invalid_ply + if tokens[1] == b'list': + obj_spec.specs[-1].properties.append(property_spec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]])) else: - texture = tokens[2] - continue - elif tokens[0] == b'obj_info': - continue - elif tokens[0] == b'format': - if len(tokens) < 3: - print('Invalid format line') - return None - if tokens[1] not in format_specs: - print('Unknown format', tokens[1]) - return None - if tokens[2] != version: - print('Unknown version', tokens[2]) - return None - format = tokens[1] - elif tokens[0] == b'element': - if len(tokens) < 3: - print(b'Invalid element line') - return None - obj_spec.specs.append(element_spec(tokens[1], int(tokens[2]))) - elif tokens[0] == b'property': - if not len(obj_spec.specs): - print('Property without element') - return None - if tokens[1] == b'list': - obj_spec.specs[-1].properties.append(property_spec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]])) - else: - obj_spec.specs[-1].properties.append(property_spec(tokens[2], None, type_specs[tokens[1]])) - - if format != b'ascii': - file.close() # was ascii, now binary - file = open(filepath, 'rb') + obj_spec.specs[-1].properties.append(property_spec(tokens[2], None, type_specs[tokens[1]])) + if not valid_header: + print("Invalid header ('end_header' line not found!)") + return invalid_ply - # skip the header... - while not file.readline().startswith(b'end_header'): - pass - - obj = obj_spec.load(format_specs[format], file) - - file.close() + obj = obj_spec.load(format_specs[format], plyf) return obj_spec, obj, texture @@ -364,6 +360,8 @@ def load_ply(filepath): ply_name = bpy.path.display_name_from_filepath(filepath) mesh = load_ply_mesh(filepath, ply_name) + if not mesh: + return {'CANCELLED'} scn = bpy.context.scene @@ -373,8 +371,8 @@ def load_ply(filepath): obj.select = True print('\nSuccessfully imported %r in %.3f sec' % (filepath, time.time() - t)) + return {'FINISHED'} def load(operator, context, filepath=""): - load_ply(filepath) - return {'FINISHED'} + return load_ply(filepath) -- GitLab