Skip to content

set_env: a quoted value ending with a literal backslash loses its quote protection #4387

Closed

Description

@haigou-web

Describe the bug

A quoted set_env value loses its quote protection as soon as it ends with a literal backslash and contains a semicolon: tox then reads the remainder of the value as a marker and aborts.

To Reproduce

tox 4.67.11, tox.ini:

[testenv]
package = skip
set_env =
    WINPATH="C:\tools;C:\bin\\"
commands = python -c "import os; print(os.environ['WINPATH'])"
ValueError: invalid marker for set_env key 'WINPATH': Expected a marker variable or quoted string
    C:\bin\\"
    ^
escape a literal ';' in the value as '\;'

Expected

The value stays "C:\tools;C:\bin\\": the quotes are balanced, the ; sits inside them, so there is no marker.

Root cause

SetEnv._split_value_marker decides whether a quote or a semicolon is escaped by inspecting the single preceding character:

if respect_quotes and char in {'"', "'"} and (index == 0 or value[index - 1] != "\\"):

For "C:\tools;C:\bin\\" the closing quote is preceded by \\, which is a literal backslash rather than an escaped quote. The first pass therefore never closes the quote and ends with in_quotes = True, so the method retries with respect_quotes = False, splits on the first ; inside the quotes and turns the rest into a marker.

Counting the run of backslashes (odd = escaped, even = literal) fixes this, and makes \\; separate correctly as well.

Workaround

Escape the semicolons instead of quoting: WINPATH=C:\tools\;C:\bin\\.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions