Added (in) sanity checks for stl files

This commit is contained in:
Sebastian 2013-12-26 13:52:56 +01:00
parent 856343bffd
commit 23caadad93
2 changed files with 72 additions and 4 deletions

View File

@ -1,16 +1,86 @@
import re
import os
import struct
from django.forms import ModelForm
from django import forms
from models import Geometry
facet_pattern = re.compile(r'facet normal\s+[0-9.e+-]+\s+[0-9.e+-]+\s+[0-9.e+-]+')
loop_pattern = re.compile(r'outer\s+loop')
vertex_pattern = re.compile(r'vertex\s+[0-9.e+-]+\s+[0-9.e+-]+\s+[0-9.e+-]+')
endloop_pattern = re.compile(r'endloop')
endfacet_pattern = re.compile(r'endfacet')
endsolid_pattern = re.compile(r'endsolid .*')
class GeometryForm(ModelForm):
class STLUploadForm(ModelForm):
def clean_file(self):
stlfile = self.cleaned_data.get("file")
stlfile.open()
print dir(stlfile)
if stlfile.read(5) != "solid":
print "binary"
#Skip header
stlfile.seek(80)
count = struct.unpack("i",stlfile.read(4))[0]
if stlfile.size - 84 != count * 50:
raise forms.ValidationError("Not a valid binary STL file.")
else:
print "ascii"
next_patterns = [facet_pattern]
stlfile.readline()
line = stlfile.readline().strip()
matched_pattern = None
vertex_count = 0
while line != "":
corret = False
for pattern in next_patterns:
if pattern.match(line) != None:
corret = True
matched_pattern = pattern
if not corret:
raise forms.ValidationError("Not a valid ascii STL file.")
if matched_pattern == facet_pattern:
next_patterns = [loop_pattern]
if matched_pattern == loop_pattern:
vertex_count = 0
next_patterns = [vertex_pattern]
if matched_pattern == vertex_pattern:
vertex_count += 1
if vertex_count < 3:
next_patterns = [vertex_pattern, endloop_pattern]
else :
next_patterns = [endloop_pattern]
if matched_pattern == endloop_pattern:
next_patterns = [endfacet_pattern]
if matched_pattern == endfacet_pattern:
next_patterns = [facet_pattern, endsolid_pattern]
line = stlfile.readline().strip()
if matched_pattern != endsolid_pattern:
raise forms.ValidationError("Not a valid ascii STL file.")
stlfile.close()
return stlfile
class GeometryForm(STLUploadForm):
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile']
class AnonymousGeometryForm(ModelForm):
class AnonymousGeometryForm(STLUploadForm):
expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1])
class Meta:
model = Geometry

View File

@ -9,8 +9,6 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.db import models
vertex_pattern = re.compile(r'vertex\s+([0-9.e+-]+)\s+([0-9.e+-]+)\s+([0-9.e+-]+)')
def safe_upload_path(base_dir):