From 141885539b7213c327a08153f49f1b8736c2e73e Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Mon, 6 Nov 2017 15:27:46 +0100
Subject: [PATCH] OO-3108: close the file system created for zip files, set
 default encoding to UTF-8 for some stream to string operations

---
 .../java/de/bps/onyx/plugin/OnyxModule.java    |  1 +
 .../java/org/olat/core/util/PathUtils.java     | 18 ++++++++++++++++++
 .../util/mail/manager/MailManagerImpl.java     |  6 +++---
 .../ui/UploadCertificateController.java        |  2 ++
 .../fileresource/types/FeedFileResource.java   |  1 +
 .../olat/fileresource/types/FileResource.java  |  6 +++++-
 .../fileresource/types/GlossaryResource.java   |  3 ++-
 .../fileresource/types/ImsCPFileResource.java  |  1 +
 .../fileresource/types/ImsQTI21Resource.java   |  1 +
 .../types/ScormCPFileResource.java             |  1 +
 .../olat/fileresource/types/WikiResource.java  |  3 ++-
 .../qti/fileresource/SurveyFileResource.java   |  1 +
 .../ims/qti/fileresource/TestFileResource.java |  1 +
 .../olat/ims/qti/qpool/QTIImportProcessor.java | 13 ++++++++++++-
 .../ims/qti21/pool/QTI21ImportProcessor.java   |  5 +++--
 .../handlers/QTI21AssessmentTestHandler.java   |  2 ++
 .../java/org/olat/login/AboutController.java   |  2 +-
 .../forms/handler/EvaluationFormHandler.java   |  2 ++
 .../forms/handler/EvaluationFormResource.java  |  1 +
 .../handler/BinderTemplateResource.java        |  2 ++
 .../org/olat/modules/wiki/WikiManager.java     |  2 ++
 .../portfolio/manager/EPXStreamHandler.java    |  2 +-
 .../RepositoryEntryImportExport.java           |  7 ++++++-
 .../repository/handlers/CourseHandler.java     |  2 ++
 .../olat/restapi/support/MultipartReader.java  |  4 +++-
 .../olat/core/util/SimpleHtmlParserTest.java   |  4 ++--
 .../olat/fileresource/FileResourceTest.java    |  2 ++
 27 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/src/main/java/de/bps/onyx/plugin/OnyxModule.java b/src/main/java/de/bps/onyx/plugin/OnyxModule.java
index 9e9d130c966..2310cca407e 100644
--- a/src/main/java/de/bps/onyx/plugin/OnyxModule.java
+++ b/src/main/java/de/bps/onyx/plugin/OnyxModule.java
@@ -234,6 +234,7 @@ public class OnyxModule extends AbstractSpringModule implements ConfigOnOff {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch(NoSuchFileException nsfe) {
 			eval.setValid(false);
 		} catch (IOException | IllegalArgumentException e) {
diff --git a/src/main/java/org/olat/core/util/PathUtils.java b/src/main/java/org/olat/core/util/PathUtils.java
index 9049f40fee8..6de5e5aeff3 100644
--- a/src/main/java/org/olat/core/util/PathUtils.java
+++ b/src/main/java/org/olat/core/util/PathUtils.java
@@ -34,6 +34,8 @@ import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ServiceConfigurationError;
 
+import org.apache.commons.io.IOUtils;
+
 /**
  * 
  * Initial date: 08.05.2014<br>
@@ -59,6 +61,16 @@ public class PathUtils {
 		return true;
 	}
 	
+	/**
+	 * Use the closeSubsequentFS method to close the file system.
+	 * 
+	 * @param file The file to visit
+	 * @param filename The filename
+	 * @param visitor The visitor
+	 * @return
+	 * @throws IOException
+	 * @throws IllegalArgumentException
+	 */
 	public static Path visit(File file, String filename, FileVisitor<Path> visitor) 
 	throws IOException, IllegalArgumentException {
 		if(!StringHelper.containsNonWhitespace(filename)) {
@@ -83,6 +95,12 @@ public class PathUtils {
 		return fPath;
 	}
 	
+	public static void closeSubsequentFS(Path path) {
+		if(path != null && FileSystems.getDefault() != path.getFileSystem()) {
+			IOUtils.closeQuietly(path.getFileSystem());
+		}
+	}
+	
 	public static class YesMatcher implements PathMatcher {
 		@Override
 		public boolean matches(Path path) {
diff --git a/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java b/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
index a4c8b902e88..a29a627cea8 100644
--- a/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
+++ b/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
@@ -603,7 +603,7 @@ public class MailManagerImpl implements MailManager, InitializingBean  {
 		File template = new File(baseFolder, "mail_template.html");
 		if(template.exists()) {
 			try(InputStream in = new FileInputStream(template)) {
-				return IOUtils.toString(in);
+				return IOUtils.toString(in, "UTF-8");
 			} catch (IOException e) {
 				log.error("", e);
 			}
@@ -622,7 +622,7 @@ public class MailManagerImpl implements MailManager, InitializingBean  {
 			File templateFile = new File(baseFolder, "mail_template.html");
 			StringReader reader = new StringReader(template);
 			out = new FileOutputStream(templateFile);
-			IOUtils.copy(reader, out);
+			IOUtils.copy(reader, out, "UTF-8");
 		} catch (IOException e) {
 			log.error("", e);
 		} finally {
@@ -633,7 +633,7 @@ public class MailManagerImpl implements MailManager, InitializingBean  {
 	@Override
 	public String getDefaultMailTemplate() {
 		try(InputStream in = MailModule.class.getResourceAsStream("_content/mail_template.html")) {
-			return IOUtils.toString(in);
+			return IOUtils.toString(in, "UTF-8");
 		} catch (IOException e) {
 			log.error("Cannot read the default mail template", e);
 			return null;
diff --git a/src/main/java/org/olat/course/certificate/ui/UploadCertificateController.java b/src/main/java/org/olat/course/certificate/ui/UploadCertificateController.java
index 043c002530f..337649b9984 100644
--- a/src/main/java/org/olat/course/certificate/ui/UploadCertificateController.java
+++ b/src/main/java/org/olat/course/certificate/ui/UploadCertificateController.java
@@ -46,6 +46,7 @@ import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.util.PathUtils;
 import org.olat.course.certificate.CertificateTemplate;
 import org.olat.course.certificate.CertificatesManager;
 import org.olat.fileresource.types.FileResource;
@@ -191,6 +192,7 @@ public class UploadCertificateController extends FormBasicController {
 					fileEl.setErrorKey("upload.error.noindex", null);
 				}
 				allOk = visitor.hasFound();
+				PathUtils.closeSubsequentFS(path);
 
 				formatEl.setVisible(allOk);
 				orientationEl.setVisible(allOk);
diff --git a/src/main/java/org/olat/fileresource/types/FeedFileResource.java b/src/main/java/org/olat/fileresource/types/FeedFileResource.java
index cd986afc68c..87f72cdaab9 100644
--- a/src/main/java/org/olat/fileresource/types/FeedFileResource.java
+++ b/src/main/java/org/olat/fileresource/types/FeedFileResource.java
@@ -94,6 +94,7 @@ public abstract class FeedFileResource extends FileResource {
 					eval.setDescription(feed.getDescription());
 				}
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 		}
diff --git a/src/main/java/org/olat/fileresource/types/FileResource.java b/src/main/java/org/olat/fileresource/types/FileResource.java
index 871a07eb014..aecac217358 100644
--- a/src/main/java/org/olat/fileresource/types/FileResource.java
+++ b/src/main/java/org/olat/fileresource/types/FileResource.java
@@ -39,6 +39,7 @@ import org.olat.core.id.OLATResourceable;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.CodeHelper;
+import org.olat.core.util.PathUtils;
 import org.olat.core.util.PathUtils.CopyVisitor;
 import org.olat.core.util.PathUtils.YesMatcher;
 import org.olat.core.util.StringHelper;
@@ -94,7 +95,9 @@ public class FileResource implements OLATResourceable {
 
 	
 	/**
-	 * This method open a new FileSystem for zip
+	 * This method open a new FileSystem for zip, please close
+	 * it with PathUtils.closeSubsequentFS()
+	 * 
 	 * @param file
 	 * @param filename
 	 * @return
@@ -143,6 +146,7 @@ public class FileResource implements OLATResourceable {
 			
 			Path destDir = targetDirectory.toPath();
 			Files.walkFileTree(path, new CopyVisitor(path, destDir, filter));
+			PathUtils.closeSubsequentFS(path);
 			return true;
 		} catch (IOException e) {
 			log.error("", e);
diff --git a/src/main/java/org/olat/fileresource/types/GlossaryResource.java b/src/main/java/org/olat/fileresource/types/GlossaryResource.java
index fd16ed1861e..0b93f44fb60 100644
--- a/src/main/java/org/olat/fileresource/types/GlossaryResource.java
+++ b/src/main/java/org/olat/fileresource/types/GlossaryResource.java
@@ -89,7 +89,7 @@ public class GlossaryResource extends FileResource {
 		ResourceEvaluation eval = new ResourceEvaluation();
 		try {
 			GlossaryFileFilter visitor = new GlossaryFileFilter();
-			PathUtils.visit(file, filename, visitor);
+			Path fPath = PathUtils.visit(file, filename, visitor);
 			if(visitor.hasFile()) {
 				XMLScanner scanner = new XMLScanner();
 				scanner.scan(visitor.glossaryFile);
@@ -97,6 +97,7 @@ public class GlossaryResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 		}
diff --git a/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java b/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java
index b2143fabe4f..1e8821a8aac 100644
--- a/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java
+++ b/src/main/java/org/olat/fileresource/types/ImsCPFileResource.java
@@ -97,6 +97,7 @@ public class ImsCPFileResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/fileresource/types/ImsQTI21Resource.java b/src/main/java/org/olat/fileresource/types/ImsQTI21Resource.java
index d6b1fe58e42..d418c73d498 100644
--- a/src/main/java/org/olat/fileresource/types/ImsQTI21Resource.java
+++ b/src/main/java/org/olat/fileresource/types/ImsQTI21Resource.java
@@ -95,6 +95,7 @@ public class ImsQTI21Resource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java b/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java
index a025776a8a1..acc5f9aa1a0 100644
--- a/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java
+++ b/src/main/java/org/olat/fileresource/types/ScormCPFileResource.java
@@ -94,6 +94,7 @@ public class ScormCPFileResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/fileresource/types/WikiResource.java b/src/main/java/org/olat/fileresource/types/WikiResource.java
index 1b84073425d..931d2e563fe 100644
--- a/src/main/java/org/olat/fileresource/types/WikiResource.java
+++ b/src/main/java/org/olat/fileresource/types/WikiResource.java
@@ -63,8 +63,9 @@ public class WikiResource extends FileResource {
 		ResourceEvaluation eval = new ResourceEvaluation();
 		try {
 			IndexFileFilter visitor = new IndexFileFilter();
-			PathUtils.visit(file, filename, visitor);
+			Path fPath = PathUtils.visit(file, filename, visitor);
 			eval.setValid(visitor.isValid());
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 		}
diff --git a/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java b/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java
index 95aa95cc3c8..f3c43165838 100644
--- a/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java
+++ b/src/main/java/org/olat/ims/qti/fileresource/SurveyFileResource.java
@@ -100,6 +100,7 @@ public class SurveyFileResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java b/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java
index 5a3f487412a..25ce767d1ab 100644
--- a/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java
+++ b/src/main/java/org/olat/ims/qti/fileresource/TestFileResource.java
@@ -131,6 +131,7 @@ public class TestFileResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
index b70007cfe93..2a5282266fa 100644
--- a/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
+++ b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
@@ -21,6 +21,7 @@ package org.olat.ims.qti.qpool;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -56,6 +57,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.PathUtils;
 import org.olat.core.util.PathUtils.CopyVisitor;
 import org.olat.core.util.PathUtils.YesMatcher;
 import org.olat.core.util.StringHelper;
@@ -142,6 +144,10 @@ class QTIImportProcessor {
 					qItems.addAll(processdItems);
 					dbInstance.commit();
 				}
+
+				for(DocInfos docInfos:docInfoList) {
+					IOUtils.closeQuietly(docInfos);
+				}
 			}
 		} catch (IOException e) {
 			log.error("", e);
@@ -793,7 +799,7 @@ class QTIImportProcessor {
 		}
 	}
 	
-	public static class DocInfos {
+	public static class DocInfos implements Closeable {
 		private Document doc;
 		private String filename;
 		private Path root;
@@ -839,5 +845,10 @@ class QTIImportProcessor {
 		public void setQtiComment(String qtiComment) {
 			this.qtiComment = qtiComment;
 		}
+
+		@Override
+		public void close() throws IOException {
+			PathUtils.closeSubsequentFS(root);
+		}
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21ImportProcessor.java b/src/main/java/org/olat/ims/qti21/pool/QTI21ImportProcessor.java
index 45b2943d2ef..e8b13c279f7 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI21ImportProcessor.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI21ImportProcessor.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
 import java.io.Writer;
 import java.net.URI;
 import java.nio.charset.Charset;
+import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
@@ -121,8 +122,8 @@ public class QTI21ImportProcessor {
 	public List<QuestionItem> process(File file) {
 		//export zip file
 		List<QuestionItem> items = new ArrayList<>();
-		try {
-			Path fPath = FileSystems.newFileSystem(file.toPath(), null).getPath("/");
+		try(FileSystem fs = FileSystems.newFileSystem(file.toPath(), null)) {
+			Path fPath = fs.getPath("/");
 			if(fPath != null) {
 				ImsManifestVisitor visitor = new ImsManifestVisitor();
 			    Files.walkFileTree(fPath, visitor);
diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
index c3e38028320..68042a6a249 100644
--- a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
+++ b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
@@ -47,6 +47,7 @@ import org.olat.core.id.Roles;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.PathUtils;
 import org.olat.core.util.PathUtils.YesMatcher;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.LockResult;
@@ -300,6 +301,7 @@ public class QTI21AssessmentTestHandler extends FileHandler {
 			QTI21IMSManifestExplorerVisitor visitor = new QTI21IMSManifestExplorerVisitor();
 			Files.walkFileTree(path, visitor);
 			Files.walkFileTree(path, new CopyAndConvertVisitor(path, destDir, visitor.getInfos(), new YesMatcher()));
+			PathUtils.closeSubsequentFS(path);
 			return true;
 		} catch (IOException e) {
 			log.error("", e);
diff --git a/src/main/java/org/olat/login/AboutController.java b/src/main/java/org/olat/login/AboutController.java
index 7314d4939cb..9cdd2aed610 100644
--- a/src/main/java/org/olat/login/AboutController.java
+++ b/src/main/java/org/olat/login/AboutController.java
@@ -70,7 +70,7 @@ public class AboutController extends BasicController {
 				licensesStream = new FileInputStream(noticeFile);			
 			}
 			if(licensesStream != null) {
-				licenses = IOUtils.toString(licensesStream);
+				licenses = IOUtils.toString(licensesStream, "UTF-8");
 			}
 		} catch (IOException e) {
 			logError("Error while reading NOTICE.TXT", e);
diff --git a/src/main/java/org/olat/modules/forms/handler/EvaluationFormHandler.java b/src/main/java/org/olat/modules/forms/handler/EvaluationFormHandler.java
index cb682583854..182a84f4f00 100644
--- a/src/main/java/org/olat/modules/forms/handler/EvaluationFormHandler.java
+++ b/src/main/java/org/olat/modules/forms/handler/EvaluationFormHandler.java
@@ -50,6 +50,7 @@ import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.PathUtils;
 import org.olat.core.util.PathUtils.YesMatcher;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
@@ -177,6 +178,7 @@ public class EvaluationFormHandler implements RepositoryHandler {
 			
 			Path destDir = targetDirectory.toPath();
 			Files.walkFileTree(path, new CopyVisitor(path, destDir, new YesMatcher()));
+			PathUtils.closeSubsequentFS(path);
 			return true;
 		} catch (IOException e) {
 			log.error("", e);
diff --git a/src/main/java/org/olat/modules/forms/handler/EvaluationFormResource.java b/src/main/java/org/olat/modules/forms/handler/EvaluationFormResource.java
index 1bd7c490c1f..5b99088708b 100644
--- a/src/main/java/org/olat/modules/forms/handler/EvaluationFormResource.java
+++ b/src/main/java/org/olat/modules/forms/handler/EvaluationFormResource.java
@@ -68,6 +68,7 @@ public class EvaluationFormResource extends FileResource {
 			} else {
 				eval.setValid(false);
 			}
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java
index d2fde5c415e..db001646174 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateResource.java
@@ -81,6 +81,8 @@ public class BinderTemplateResource extends FileResource  {
 			} else {
 				eval.setValid(false);
 			}
+			
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 			eval.setValid(false);
diff --git a/src/main/java/org/olat/modules/wiki/WikiManager.java b/src/main/java/org/olat/modules/wiki/WikiManager.java
index 54cf14fdeea..7ee99aeb105 100644
--- a/src/main/java/org/olat/modules/wiki/WikiManager.java
+++ b/src/main/java/org/olat/modules/wiki/WikiManager.java
@@ -54,6 +54,7 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.logging.activity.LearningResourceLoggingAction;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.PathUtils;
 import org.olat.core.util.cache.CacheWrapper;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.resource.OresHelper;
@@ -171,6 +172,7 @@ public class WikiManager {
 			
 			Path destDir = targetDirectory.toPath();
 			Files.walkFileTree(path, new ImportVisitor(destDir));
+			PathUtils.closeSubsequentFS(path);
 			return true;
 		} catch (IOException e) {
 			log.error("", e);
diff --git a/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java b/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java
index 7a0c4647cd9..41b5f5fd952 100644
--- a/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java
+++ b/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java
@@ -115,7 +115,7 @@ public class EPXStreamHandler {
 				Transformer transformer = filterArtefactsTemplates.newTransformer();
 				transformer.transform(new StreamSource(zipIn), new StreamResult(buffer));
 			} else {
-				IOUtils.copy(zipIn, buffer);
+				IOUtils.copy(zipIn, buffer, "UTF-8");
 			}
 
 			PortfolioStructure struct = (PortfolioStructure) myStream.fromXML(buffer.toString());
diff --git a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java
index b1ae92d834a..89f6cfff59e 100644
--- a/src/main/java/org/olat/repository/RepositoryEntryImportExport.java
+++ b/src/main/java/org/olat/repository/RepositoryEntryImportExport.java
@@ -30,6 +30,7 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -275,10 +276,12 @@ public class RepositoryEntryImportExport {
 	 * Read previousely exported Propertiesproperties
 	 */
 	private void loadConfiguration() {
+		FileSystem fs = null;
 		try {
 			if(baseDirectory.exists()) {
 				if(baseDirectory.getName().endsWith(".zip")) {
-					Path fPath = FileSystems.newFileSystem(baseDirectory.toPath(), null).getPath("/");
+					fs = FileSystems.newFileSystem(baseDirectory.toPath(), null);
+					Path fPath = fs.getPath("/");
 					Path manifestPath = fPath.resolve("export").resolve(PROPERTIES_FILE);
 					try(InputStream inputFile = Files.newInputStream(manifestPath, StandardOpenOption.READ)) {
 						XStream xstream = getXStream();
@@ -301,6 +304,8 @@ public class RepositoryEntryImportExport {
 			propertiesLoaded = true;
 		} catch (Exception ce) {
 			throw new OLATRuntimeException("Error importing repository entry properties.", ce);
+		} finally {
+			IOUtils.closeQuietly(fs);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java
index c2cfbf27621..49cb4054e56 100644
--- a/src/main/java/org/olat/repository/handlers/CourseHandler.java
+++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java
@@ -185,6 +185,8 @@ public class CourseHandler implements RepositoryHandler {
 				}
 			}
 			eval.setValid(visitor.isValid());
+			
+			PathUtils.closeSubsequentFS(fPath);
 		} catch (IOException | IllegalArgumentException e) {
 			log.error("", e);
 		}
diff --git a/src/main/java/org/olat/restapi/support/MultipartReader.java b/src/main/java/org/olat/restapi/support/MultipartReader.java
index ad260361b75..0726cf7bb1e 100644
--- a/src/main/java/org/olat/restapi/support/MultipartReader.java
+++ b/src/main/java/org/olat/restapi/support/MultipartReader.java
@@ -51,6 +51,8 @@ public class MultipartReader {
 		servlet31(request);
 	}
 	private final void servlet31(HttpServletRequest request) {
+		
+		
 		try {
 			for(Part part:request.getParts()) {
 				if(part.getContentType() != null) {
@@ -65,7 +67,7 @@ public class MultipartReader {
 					part.write(file.getAbsolutePath());
 					file = new File(WebappHelper.getTmpDir(), filename);
 				} else {
-					String value = IOUtils.toString(part.getInputStream());
+					String value = IOUtils.toString(part.getInputStream(), request.getCharacterEncoding());
 					fields.put(part.getName(), value);
 				}
 				
diff --git a/src/test/java/org/olat/core/util/SimpleHtmlParserTest.java b/src/test/java/org/olat/core/util/SimpleHtmlParserTest.java
index e75a35053a8..d87b58f21a3 100644
--- a/src/test/java/org/olat/core/util/SimpleHtmlParserTest.java
+++ b/src/test/java/org/olat/core/util/SimpleHtmlParserTest.java
@@ -37,7 +37,7 @@ public class SimpleHtmlParserTest {
 	@Test
 	public void parse_minimalTinyMCEHTMLPage() throws IOException {
 		InputStream inHtml = SimpleHtmlParserTest.class.getResourceAsStream("simple_1.html");
-		String html = IOUtils.toString(inHtml);
+		String html = IOUtils.toString(inHtml, "UTF-8");
 		
 		SimpleHtmlParser parser = new SimpleHtmlParser(html);
 		Assert.assertEquals("<body>", parser.getBodyTag());
@@ -52,7 +52,7 @@ public class SimpleHtmlParserTest {
 	@Test
 	public void parse_externHtmlEditor() throws IOException {
 		InputStream inHtml = SimpleHtmlParserTest.class.getResourceAsStream("simple_2.html");
-		String html = IOUtils.toString(inHtml);
+		String html = IOUtils.toString(inHtml, "UTF-8");
 		
 		SimpleHtmlParser parser = new SimpleHtmlParser(html);
 		Assert.assertEquals("<body>", parser.getBodyTag());
diff --git a/src/test/java/org/olat/fileresource/FileResourceTest.java b/src/test/java/org/olat/fileresource/FileResourceTest.java
index f8f503857b3..a58e19467f7 100644
--- a/src/test/java/org/olat/fileresource/FileResourceTest.java
+++ b/src/test/java/org/olat/fileresource/FileResourceTest.java
@@ -27,6 +27,7 @@ import java.nio.file.Path;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.olat.core.util.PathUtils;
 import org.olat.fileresource.types.FileResource;
 import org.olat.fileresource.types.ResourceEvaluation;
 import org.olat.fileresource.types.ScormCPFileResource;
@@ -81,6 +82,7 @@ public class FileResourceTest {
 		Path path = FileResource.getResource(file, file.getName());
 		//must be root
 		Assert.assertEquals(0, path.getNameCount());
+		PathUtils.closeSubsequentFS(path);
 	}
 	
 
-- 
GitLab