From 23caadad93a5378fd0664e8898b7a0f2c7de8973 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Thu, 26 Dec 2013 13:52:56 +0100 Subject: [PATCH] Added (in) sanity checks for stl files --- pastebin/forms.py | 74 ++++++++++++++++++++++++++++++++++++++++++++-- pastebin/models.py | 2 -- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/pastebin/forms.py b/pastebin/forms.py index b984c0a..917fd9d 100644 --- a/pastebin/forms.py +++ b/pastebin/forms.py @@ -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 diff --git a/pastebin/models.py b/pastebin/models.py index e079b2b..ddeca43 100644 --- a/pastebin/models.py +++ b/pastebin/models.py @@ -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):