compose: Escape sequences cannot be used inside quoted strings

Description of the issue

Docker Compose v2 (compose-go) is stripping out escape characters when inside of a quoted string in a command (might happen in other circumstances).

If it’s not in a quoted string, they are left as-is. For example, command: printf 'Hello\tworld\n' works while command: sh -c "printf 'Hello\tworld\n'" does not.

Context information (for bug reports)

  • Using Compose V2 docker compose ...
  • Using Compose V1 docker-compose ...

Output of docker(-)compose version

Docker Compose version v2.0.0-rc.2

Output of docker version

Client:
 Cloud integration: 1.0.17
 Version:           20.10.8
 API version:       1.41
 Go version:        go1.16.6
 Git commit:        3967b7d
 Built:             Fri Jul 30 19:55:20 2021
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.8
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.6
  Git commit:       75249d8
  Built:            Fri Jul 30 19:52:10 2021
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          1.4.9
  GitCommit:        e25210fe30a0a703442421b0f60afac609f950a3
 runc:
  Version:          1.0.1
  GitCommit:        v1.0.1-0-g4144b63
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Output of docker-compose config w/ v2 (v2.0.0-rc.2):

services:
  hello-world:
    command:
    - sh
    - -c
    - printf 'Hellotworldn'
    image: busybox
    networks:
      default: null
networks:
  default:
    name: escape-repro_default

w/ v1 (1.29.2, build 5becea4c):

services:
  hello-world:
    command: sh -c "printf 'Hello\tworld\n'"
    image: busybox
version: '3.9'

Steps to reproduce the issue

  1. Use an escape sequence (e.g. \t or \n) inside of a quoted string in command

Observed result

  • Docker Compose v2 (compose-go) strips out the \ characters

Expected result

  • Docker Compose leaves the \ characters as-is

Stacktrace / full error message

n/a

Additional information

n/a

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 1
  • Comments: 16 (3 by maintainers)

Most upvoted comments

this is for sure an issue, but we don’t have any simple solution here. docker-compose v1 is coded in python, and relies on python’s shlex to parse the command attribute. There’s no direct equivalent in Go.

The root issue here is that command has been introduce with the assumption we can strictly reproduce shell script parsing in compose codebase. That makes the tool more convenient to configure for users, but some corner cases exists.

I recently also stumbled upon that issue and it is currently present in many test setups for TYPO3 and it’s extensions.

E.g. here: https://github.com/TYPO3/styleguide/blob/3baee32b70d60fe13741435597053c240ccc3463/Build/testing-docker/docker-compose.yml#L294

The lines

  XDEBUG_MODE=\"off\" \
  bin/phpunit -c Web/typo3conf/ext/styleguide/Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE};

are executed not as one, but two lines and therefore the XDEBUG_MODE variable is not used by the phpunit command afterwards.

I’m using Debian 12 and docker-compose v2.17.0, another user i chatted with who also had problems with that used Ubuntu 23.04 and docker-compose v2.17.2.

Is this something that can and should be fixed in docker-compose or should we rewrite our docker-compose.yml files?

I can confirm this is still the case as of v2.3.3