SDL_mixer: Added support of quoted strings in Timidity config

From 1c0092787398097360f7da745c7644fd32697f3b Mon Sep 17 00:00:00 2001
From: Dasperal <[EMAIL REDACTED]>
Date: Mon, 22 Nov 2021 23:22:30 +0300
Subject: [PATCH] Added support of quoted strings in Timidity config

---
 src/codecs/timidity/timidity.c | 58 ++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/src/codecs/timidity/timidity.c b/src/codecs/timidity/timidity.c
index 0f43de4c..ef4a2e7f 100644
--- a/src/codecs/timidity/timidity.c
+++ b/src/codecs/timidity/timidity.c
@@ -97,10 +97,62 @@ static int read_config_file(const char *name, int rcf_count)
     if (*w[0] == '#')
         continue;
 
-    while (w[words] && *w[words] != '#') {
-      if (++words == MAXWORDS) break;
-      w[words]=SDL_strtokr(NULL, " \t\240", &endp);
+    while (words < MAXWORDS - 1) /* -1 : next arg */
+    {
+      while (*endp == ' ' || *endp == '\t' || *endp == '\240')
+        endp++;
+      if (*endp == '\0' || *endp == '#')
+        break;
+      if (*endp == '"' || *endp == '\'') /* quoted string */
+      {
+        char *terminator;
+        if ((terminator = SDL_strchr(endp + 1, *endp)) != NULL) /* terminated */
+        {
+          if (terminator[1] == ' ' || terminator[1] == '\t' || terminator[1] == '\240' || terminator[1] == '\0')
+          {
+            char *extraQuote;
+            if ((extraQuote = SDL_strchr(endp + 1, *endp == '"' ? '\'' : '"')) != NULL && extraQuote < terminator)
+            {
+                SNDDBG(("%s: line %d: Quote characters are not allowed inside a quoted string", name, line));
+                goto fail;
+            }
+
+            w[++words] = endp + 1;
+            endp = terminator + 1;
+            *terminator = '\0';
+          }
+          else /* no space after quoted string */
+          {
+            SNDDBG(("%s: line %d: There must be at least one whitespace between string terminator (%c) and the next parameter", name, line, *endp));
+            goto fail;
+          }
+        }
+        else /* not terminated */
+        {
+          SNDDBG(("%s: line %d: The quoted string is not terminated", name, line));
+          goto fail;
+        }
+      }
+      else /* not quoted string */
+      {
+        w[++words] = endp;
+        while (!(*endp == ' ' || *endp == '\t' || *endp == '\240' || *endp == '\0'))
+        {
+          if (*endp == '"' || *endp == '\'') /* no space before quoted string */
+          {
+              SNDDBG(("%s: line %d: There must be at least one whitespace between previous parameter and a beginning of the quoted string (%c)", name, line, *endp));
+              goto fail;
+          }
+          endp++;
+        }
+        if (*endp != '\0') /* unless at the end-of-string (i.e. EOF) */
+        {
+          *endp = '\0';    /* terminate the token */
+          endp++;
+        }
+      }
     }
+    w[++words] = NULL;
 
     /* TiMidity++ adds a number of extensions to the config file format.
      * Many of them are completely irrelevant to SDL_sound, but at least