Skip to content

Conversation

@jpue
Copy link
Contributor

@jpue jpue commented Dec 1, 2025

Reported: https://www.qlcplus.org/forum/viewtopic.php?t=18935

Describe the bug / To Reproduce / Expected behaviour

  1. Start QLC+ (v4, new workspace).
  2. Add a new Script function and paste the following code:
systemcommand:cmdline arg:abc arg:def arg:"gh i" arg:"j'k'l m" arg:n"op"q
systemcommand:cmdline arg:"--geometry=45x7" arg:"--hide-menubar" arg:"--" arg:"mpv" arg:"/path/to/my/file.mp3"

with cmdline being the following helper bash script:

#!/bin/bash
echo -ne "$#|" >> "output.txt"
while [[ $# -gt 0 ]]; do
  echo -ne "$1|" >> "output.txt"
  shift
done
echo >> "output.txt"

(change the paths as necessary).

  1. Run the QLC+ script and verify that the contents of output.txt match:
5|abc|def|gh i|j'k'l m|n"op"q|
5|--geometry=45x7|--hide-menubar|--|mpv|/path/to/my/file.mp3|
  1. Save the workspace, close QLC+ (v4) and open/import the workspace into QLC+ v5. Open the script and verify that it matches:
Engine.systemCommand("../cmdline abc def 'gh i' 'j'k'l m' n"op"q");
Engine.systemCommand("../cmdline '--geometry=45x7' '--hide-menubar' '--' 'mpv' '/path/to/my/file.mp3'");
  1. Check the script with the syntax checker.
    Bug A: The (double) quotes in the last argument of the first line were not escaped during the script conversion from v4 to v5. This is an issue and prevents the script from running.
  2. Temporarily fix the problem by placing backslashes in front of the quotes. (Result: n\"op\"q). The syntax checker should now report: “No errors found.”
  3. Run the QLC+ script and verify that the contents of output.txt match:
5|abc|def|gh i|j'k'l m|n"op"q|
0|

The first line should be correct since it is equivalent to the output from QLC+ v4.
However, the second line (the example from the linked forum thread) is wrong, as it does not pass any of the specified arguments to the bash script.
Bug B: If an argument does not contain spaces, but is still enclosed in single quotes (as are all arguments in scripts converted from v4), they are skipped when the script is executed.

Problem Analysis
Bug A
The conversion code only checks whether an argument begins with quotes and then threats it accordingly. However, quotes contained within an argument are not take into account in any way. source

Bug B
The issue lies in the ScriptRunner::systemCommand function. Assuming that the current input for this function is the second line of the above test script, during the first round of this loop, the first argument begins with a single quote and is therefore written (with only the first character, the opening quotation mark, removed) to the cleaned multiPartArg string. In the next iteration (when token contains the second argument, which also begins with a single quote), multiPartArg is cleaned and the second argument is written to it. This continues for all arguments.
Therefore, at the end of the loop, no argument has been written into programArgs and the system command is launched without any arguments.

Proposed Solutions
Bug A
Add a replace call to also escape quotes in the middle of an argument

Bug B
Add another if-case before if (token.startsWith("'")) (line 450) and change the old line 450 to else if
The new if-case checks whether the token (argument) starts and ends with a single quote (and does not contain a space, which is implicitly given since all token were split from command by a space).
If this is true, simply remove the single quotes at the beginning and end, and then add the resulting string to the programArgs list.

@coveralls
Copy link

Coverage Status

coverage: 34.233%. remained the same
when pulling 74445d8 on jpue:script_v5
into d5fb37a on mcallegari:master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants