diff --git a/src/octoprint/util/__init__.py b/src/octoprint/util/__init__.py index 3f5af26b..0c5e66d2 100644 --- a/src/octoprint/util/__init__.py +++ b/src/octoprint/util/__init__.py @@ -8,6 +8,7 @@ import sys import time import re import tempfile +from flask import make_response from octoprint.settings import settings @@ -188,3 +189,38 @@ def silentRemove(file): os.remove(file) except OSError: pass + + +def sanitizeAscii(line): + return unicode(line, 'ascii', 'replace').encode('ascii', 'replace').rstrip() + + +def filterNonAscii(line): + """ + Returns True if the line contains non-ascii characters, false otherwise + + @param line the line to test + """ + + try: + unicode(line, 'ascii').encode('ascii') + return False + except ValueError: + return True + + +def getJsonCommandFromRequest(request, valid_commands): + if not "application/json" in request.headers["Content-Type"]: + return None, None, make_response("Expected content-type JSON", 400) + + data = request.json + if not "command" in data.keys() or not data["command"] in valid_commands.keys(): + return None, None, make_response("Expected valid command", 400) + + command = data["command"] + for parameter in valid_commands[command]: + if not parameter in data: + return None, None, make_response("Mandatory parameter %s missing for command %s" % (parameter, command), 400) + + return command, data, None + diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 924fef29..57599ed6 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -20,7 +20,7 @@ from octoprint.util.avr_isp import ispBase from octoprint.settings import settings from octoprint.events import eventManager from octoprint.gcodefiles import isGcodeFileName -from octoprint.util import getExceptionString, getNewTimeout +from octoprint.util import getExceptionString, getNewTimeout, sanitizeAscii, filterNonAscii from octoprint.util.virtual import VirtualPrinter try: @@ -513,7 +513,11 @@ class MachineCom(object): ##~~ SD file list # if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing if self._sdFileList and isGcodeFileName(line.strip().lower()) and not 'End file list' in line: - self._sdFiles.append(line.strip().lower()) + filename = line.strip().lower() + if filterNonAscii(filename): + self._logger.warn("Got a file from printer's SD that has a non-ascii filename (%s), that shouldn't happen according to the protocol" % filename) + else: + self._sdFiles.append(filename) continue ##~~ Temperature processing @@ -826,7 +830,7 @@ class MachineCom(object): if ret == '': #self._log("Recv: TIMEOUT") return '' - self._log("Recv: %s" % (unicode(ret, 'ascii', 'replace').encode('ascii', 'replace').rstrip())) + self._log("Recv: %s" % sanitizeAscii(ret)) return ret def _sendNext(self): @@ -1202,4 +1206,4 @@ class PrintingGcodeFileInformation(PrintingFileInformation): class StreamingGcodeFileInformation(PrintingGcodeFileInformation): def __init__(self, filename): - PrintingGcodeFileInformation.__init__(self, filename, None) \ No newline at end of file + PrintingGcodeFileInformation.__init__(self, filename, None)