From e987cd1ba35d5861aafd4bbb815c4ee0ec293d7c Mon Sep 17 00:00:00 2001
From: "Y.Tory" <5343692+kagemomiji@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:57:24 +0000
Subject: [PATCH 1/2] #357 Add pattern matching to remove leading slashes from
 file path

---
 .../airsonic/player/command/MusicFolderSettingsCommand.java   | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/airsonic-main/src/main/java/org/airsonic/player/command/MusicFolderSettingsCommand.java b/airsonic-main/src/main/java/org/airsonic/player/command/MusicFolderSettingsCommand.java
index 93547f599..392799953 100644
--- a/airsonic-main/src/main/java/org/airsonic/player/command/MusicFolderSettingsCommand.java
+++ b/airsonic-main/src/main/java/org/airsonic/player/command/MusicFolderSettingsCommand.java
@@ -20,6 +20,7 @@
  */
 package org.airsonic.player.command;
 
+import com.google.re2j.Pattern;
 import org.airsonic.player.controller.MusicFolderSettingsController;
 import org.airsonic.player.domain.MusicFolder;
 import org.airsonic.player.domain.MusicFolder.Type;
@@ -276,7 +277,8 @@ public MusicFolder toMusicFolder() {
             if (path == null) {
                 return null;
             }
-            Path file = Paths.get(path);
+            Pattern pattern = Pattern.compile("\\.+/");
+            Path file = Paths.get(pattern.matcher(path).replaceAll(""));
             String name = StringUtils.trimToNull(this.name);
             if (name == null) {
                 name = file.getFileName().toString();

From 7184894e4bd2e3d8eaf7b1cd2e455c4a03cf6a2c Mon Sep 17 00:00:00 2001
From: "Y.Tory" <5343692+kagemomiji@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:58:13 +0000
Subject: [PATCH 2/2] #357 fix uncontrolled command line by format

---
 .../player/controller/CaptionsController.java | 23 +++++++++----------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/airsonic-main/src/main/java/org/airsonic/player/controller/CaptionsController.java b/airsonic-main/src/main/java/org/airsonic/player/controller/CaptionsController.java
index 1315bd83b..d1f42ed9f 100644
--- a/airsonic-main/src/main/java/org/airsonic/player/controller/CaptionsController.java
+++ b/airsonic-main/src/main/java/org/airsonic/player/controller/CaptionsController.java
@@ -1,7 +1,5 @@
 package org.airsonic.player.controller;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.MoreFiles;
 import org.airsonic.player.domain.MediaFile;
 import org.airsonic.player.domain.User;
 import org.airsonic.player.io.InputStreamReaderThread;
@@ -14,6 +12,7 @@
 import org.airsonic.player.service.metadata.MetaDataParser;
 import org.airsonic.player.service.metadata.MetaDataParserFactory;
 import org.airsonic.player.util.NetworkUtil;
+import org.apache.commons.compress.utils.FileNameUtils;
 import org.apache.commons.io.input.BOMInputStream;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -58,7 +57,7 @@ public class CaptionsController {
 
     private static final String CAPTION_FORMAT_VTT = "vtt";
     private static final String CAPTION_FORMAT_SRT = "srt";
-    private static final Set<String> CAPTIONS_FORMATS = ImmutableSet.of(CAPTION_FORMAT_VTT, CAPTION_FORMAT_SRT);
+    private static final Set<String> CAPTIONS_FORMATS = Set.of(CAPTION_FORMAT_VTT, CAPTION_FORMAT_SRT);
 
     @Autowired
     private MediaFileService mediaFileService;
@@ -109,8 +108,8 @@ public ResponseEntity<Resource> handleRequest(
 
             if (effectiveFormat.equalsIgnoreCase(res.getFormat())) {
                 resource = getExternalResource(captionsFile, res.getFormat());
-            } else if ("srt".equals(res.getFormat()) && "vtt".equals(requiredFormat)) {
-                resource = getConvertedResource(captionsFile, "0", effectiveFormat);
+            } else if (CAPTION_FORMAT_SRT.equals(res.getFormat()) && CAPTION_FORMAT_VTT.equals(effectiveFormat)) {
+                resource = getConvertedResource(captionsFile, "0", CAPTION_FORMAT_VTT);
             } else {
                 throw new NotFoundException("No captions found for file id: " + id);
             }
@@ -123,7 +122,7 @@ public ResponseEntity<Resource> handleRequest(
 
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(CAPTION_FORMAT_VTT.equalsIgnoreCase(effectiveFormat)
-                ? new MediaType("text", "vtt", StandardCharsets.UTF_8)
+                ? new MediaType("text", CAPTION_FORMAT_VTT, StandardCharsets.UTF_8)
                 : new MediaType("text", "plain", StandardCharsets.UTF_8));
         headers.setAccessControlAllowOrigin("*");
 
@@ -162,7 +161,7 @@ public Resource getConvertedResource(Path inputFile, String identifier, String f
 
     public static String getForceFormat(String format) {
         switch (format) {
-            case "vtt":
+            case CAPTION_FORMAT_VTT:
                 return "webvtt";
             default:
                 return format;
@@ -172,9 +171,9 @@ public static String getForceFormat(String format) {
     public static String getDisplayFormat(String format) {
         switch (format) {
             case "webvtt":
-                return "vtt";
+                return CAPTION_FORMAT_VTT;
             case "subrip":
-                return "srt";
+                return CAPTION_FORMAT_SRT;
             default:
                 return format;
         }
@@ -222,7 +221,7 @@ public List<CaptionInfo> listCaptions(MediaFile video, String basePath, String e
         Stream<CaptionInfo> externalCaptions = findExternalCaptionsForVideo(video).stream()
                 .map(c -> new CaptionInfo(c.toString(), // leaks internal structure for now
                         CaptionInfo.Location.external,
-                        MoreFiles.getFileExtension(c),
+                        FileNameUtils.getExtension(c),
                         c.getFileName().toString(),
                         getUrl(basePath, externalUser, externalExpiration, video.getId(),
                                 URLEncoder.encode(c.toString(), StandardCharsets.UTF_8))));
@@ -250,7 +249,7 @@ public String getUrl(String basePath, String externalUser, Instant externalExpir
     }
 
     private Resource getExternalResource(Path captionsFile, String format) throws IOException {
-        if ("vtt".equals(format)) {
+        if (CAPTION_FORMAT_VTT.equals(format)) {
             return new PathResource(captionsFile);
         } else {
             return new InputStreamResource(new BOMInputStream(Files.newInputStream(captionsFile)));
@@ -267,7 +266,7 @@ public List<Path> findExternalCaptionsForVideo(MediaFile video) {
         try (Stream<Path> children = Files.walk(parentPath)) {
             return children.parallel()
                     .filter(c -> Files.isRegularFile(c))
-                    .filter(c -> CAPTIONS_FORMATS.contains(MoreFiles.getFileExtension(c)))
+                    .filter(c -> CAPTIONS_FORMATS.contains(FileNameUtils.getExtension(c)))
                     .collect(Collectors.toList());
         } catch (IOException e) {
             LOG.warn("Could not retrieve directory list for {} to find subtitle files for {}", parentPath, video, e);