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.forms import ModelForm
from django import forms from django import forms
from models import Geometry 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: class Meta:
model = Geometry model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile'] fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile']
class AnonymousGeometryForm(ModelForm): class AnonymousGeometryForm(STLUploadForm):
expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1]) expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1])
class Meta: class Meta:
model = Geometry model = Geometry

View File

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