diff --git a/src/octoprint/util/__init__.py b/src/octoprint/util/__init__.py index 437af118..0c5e66d2 100644 --- a/src/octoprint/util/__init__.py +++ b/src/octoprint/util/__init__.py @@ -191,6 +191,24 @@ def silentRemove(file): 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) diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 6a805d7e..091bbddf 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -23,7 +23,7 @@ from octoprint.settings import settings from octoprint.events import eventManager, Events from octoprint.filemanager.destinations import FileDestinations 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: @@ -605,7 +605,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 @@ -920,7 +924,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):