Skip to content

fix(validator): accept . , .. , and relative paths as COPY/ADD destination#132

Open
Fukuro192 wants to merge 5 commits intorcjsuen:masterfrom
Fukuro192:master
Open

fix(validator): accept . , .. , and relative paths as COPY/ADD destination#132
Fukuro192 wants to merge 5 commits intorcjsuen:masterfrom
Fukuro192:master

Conversation

@Fukuro192
Copy link

@Fukuro192 Fukuro192 commented Mar 1, 2026

Fixes the false positive where the validator reported "When using COPY/ADD with more than one source file, the destination must be a directory and end with a / or a \" for valid directory destinations.

On POSIX, . and .. are the current and parent directories, so COPY file1 file2 ., COPY file1 file2 .., and similar forms are valid. The Docker builder accepts them; per VALIDATOR.md, the validator should not error on Dockerfiles the builder can build.

Changes

  • Current and parent directory: Treat destination as valid when it is ., ./, .., or ../ (after trimming and stripping optional surrounding quotes).
  • Deeper relative paths: Use the regex /^(\.\.?[\/\\])*\.\.?[\/\\]?$/ so any relative directory path is accepted (e.g. ../.., ../../, .././../../.), not only . and ...
  • Paths with directory names: Treat destination as a directory when it is a path with one or more segments (e.g. foo/, foo/bar/, a/b/c/) and ends with / or \, using a path-segment regex plus an "ends with directory indicator" check.
  • Backslash (Windows-style): The same logic allows \ as path separator (e.g. ..\.., ..\, foo\bar\), consistent with the "end with / or \" rule.
  • Refactor: Extract the directory-destination regexes into class-level constants (IS_RELATIVE_DIR, IS_PATH_WITH_DIR_NAMES, ENDS_WITH_DIR_INDICATOR) and a shared helper isValidDirectoryDestination(), used by both checkDestinationIsDirectory and checkJsonDestinationIsDirectory, removing duplicated logic.
  • Tests:
    • . and ./ (shell and JSON) for ADD and COPY.
    • .. and ../.
    • Trailing-slash regression (./ and ../).
    • Deeper paths (../.., ../../).
    • Backslash paths (..\.., ..\) using #escape= so backslash is literal.

The invalidDestination message text is unchanged; only the condition that triggers it was relaxed.

Testing note

I've tested paths like ../.. and ../../ on Docker (multi-source COPY/ADD with those destinations succeed).
I haven't run paths using backslash (e.g. ..\..) 😅 ; the change is based on the documented rule that the destination may end with \ and on the regex accepting the same relative-dir pattern with \ as separator.

Other Note

I'm not sure if too much for such a small fix -- I'd be happy to simplify to only the behavior change if so.

…COPY/ADD

On POSIX/Linux, . denotes the current directory, so COPY file1 file2 .
and ADD file1 file2 . are valid. Relax the rule that the destination
must end with / or \ to also accept . or ./ (with optional surrounding
whitespace or quotes).

- Update checkDestinationIsDirectory and checkJsonDestinationIsDirectory
- Add tests for ADD and COPY with multiple sources and destination . or ./
…e COPY/ADD

Follow-up to accepting . and ./: also accept parent directory (.. and ../)
as valid directory destination for multi-source COPY/ADD on POSIX.
…ource COPY/ADD

Use regex /^(\.\.?\/)*\.\.?\/?$/ so relative directory destinations
like ../.. and ../../ are accepted, not only ., ./, .., ../.
Keeps trailing-slash forms (./, ../) accepted. Add tests for
trailing-slash regression and for deeper paths (../.., ../../).
… COPY/ADD

Extend relative-dir regex to accept \ as path separator (e.g. ..\.., ..\)
so Windows-style paths match the "end with / or \" rule. Add tests using
…gex helpers

- Allow COPY/ADD destination to be a directory when path has segments and
  ends with / or \ (e.g. foo/bar/), in addition to . and ..
- Add Validator regex constants and isValidDirectoryDestination() to
  replace duplicated logic in checkDestinationIsDirectory and
  checkJsonDestinationIsDirectory
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.

1 participant