Skip to content

Fix JAVA_OPTS quoting and glob expansion (#1301)#1303

Draft
stokpop wants to merge 10 commits into
cloudfoundry:mainfrom
stokpop:issue-1301-java-opts-quoting
Draft

Fix JAVA_OPTS quoting and glob expansion (#1301)#1303
stokpop wants to merge 10 commits into
cloudfoundry:mainfrom
stokpop:issue-1301-java-opts-quoting

Conversation

@stokpop
Copy link
Copy Markdown
Contributor

@stokpop stokpop commented May 28, 2026

Fixes #1301.

  • Preserve quotes and backslashes in JAVA_OPTS assembly
  • Avoid eval mangling of user JAVA_OPTS values
  • Use quoted eval start commands to prevent glob/word-splitting issues
  • Add regression tests for quoted args and cron/glob expressions

…cloudfoundry#1301)

- Replace xargs-based JAVA_OPTS normalization with newline-only normalization
  to preserve quotes and backslashes.
- Protect user-provided JAVA_OPTS during opts-file eval expansion by using a
  placeholder and restoring it after eval.
- Introduce JavaExecCommand() and switch Java Main/Spring Boot start commands
  to eval "exec ... $JAVA_OPTS ..." so shell globbing/word-splitting does not
  corrupt args.
- Add regression tests for quoted values, cron/glob expressions, multiple
  quoted args, backslashes, and start-command invocation behavior.
- Clean up overlapping/no-op test code and improve test readability.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses v5.x regressions in how the buildpack assembles and invokes JAVA_OPTS, aiming to preserve quoted JVM arguments and prevent unintended glob/word-splitting during the start-command eval path.

Changes:

  • Removes xargs from JAVA_OPTS normalization and avoids exposing user JAVA_OPTS to eval during .opts expansion.
  • Introduces a shared JavaExecCommand(...) helper so container start commands consistently use eval "exec ... $JAVA_OPTS ..." (quoted eval argument).
  • Adds/extends regression tests to cover quoted args, backslashes, and cron/glob-style expressions.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/java/frameworks/java_opts_writer.go Adjusts runtime assembly script to preserve quoting/backslashes and avoid eval-mangling of user JAVA_OPTS.
src/java/frameworks/java_opts_writer_test.go Adds regression tests for quoted args, backslashes, and glob-like cron expressions.
src/java/containers/container.go Adds JavaExecCommand(...) helper to standardize quoted-eval Java start command construction.
src/java/containers/spring_boot.go Switches Spring Boot start command construction to JavaExecCommand(...).
src/java/containers/spring_boot_test.go Verifies Spring Boot start commands use quoted eval form.
src/java/containers/java_main.go Switches Java Main start command construction to JavaExecCommand(...).
src/java/containers/java_main_test.go Adds assertions that Java Main start commands use quoted eval form (though currently placed under Describe("buildClasspath")).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/java/frameworks/java_opts_writer.go Outdated
Comment thread src/java/frameworks/java_opts_writer.go
Comment thread src/java/frameworks/java_opts_writer.go Outdated
Comment thread src/java/containers/container.go
Comment thread src/java/containers/java_main_test.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread src/java/frameworks/java_opts_writer.go Outdated
Comment thread src/java/containers/container.go
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread src/java/containers/java_main.go
Comment thread src/java/frameworks/java_opts_writer_test.go Outdated
stokpop added 2 commits June 8, 2026 12:44
…nused test param

Arguments from JBP_CONFIG_JAVA_MAIN containing double quotes would break the
outer eval "..." string in the start command. Escape them before building
the javaArgs string. Add regression test.

Rename unused 'javaOpts' param in setupScript test helper to '_' to document
that it has no effect on script generation.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/java/frameworks/java_opts_writer.go Outdated
Comment on lines +109 to +113
# Expand any remaining environment variables in opts content via eval.
# Note: eval executes commands, but .opts files are written by the buildpack
# at staging time and run within the container context.
# This matches how the Ruby buildpack naturally expanded variables via shell.
opts_content=$(eval "echo \"$opts_content\"")
opts_content=$(eval "printf '%%s' \"$opts_content\"")
eval "printf '%s' \"\$opts_content\"" mangles .opts content containing
literal double quotes (e.g. Datadog writes -Ddd.service="myapp"): the inner "
terminates the outer eval string and the value is stripped.

Escape \ (first) and " in opts_content into a temporary _eval_safe variable
before expanding it into the eval command, so both chars are preserved.

Add regression tests for double-quoted and backslash .opts values.
@stokpop stokpop marked this pull request as draft June 8, 2026 13:30
@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented Jun 8, 2026

There are many levels of escapes needed to get JAVA_OPTS replacement right with the use of eval and the need for escaping and making the quoting work correctly.

I have experimented with a solution that does not depend on eval and all the escaping rules. Let me test this an I can submit another PR as follow-up on to this one (or as replacement). Turned this PR into draft for now.

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.

v5.x regression: JAVA_OPTS handling broken (pipes/newlines in 5.0.2, quoting in 5.0.3)

2 participants