@@ -141,13 +141,13 @@ case "$USER_JAVA_OPTS" in
141141esac
142142
143143# Escape replacement-special chars once; these values are loop-invariant.
144+ # USER_JAVA_OPTS is injected via string-split below (not ${//}) — bash 4.x and 5.x
145+ # treat '\\' in replacement strings differently, corrupting backslashes.
144146_escaped_deps_dir="${DEPS_DIR//\\/\\\\}"
145147_escaped_deps_dir="${_escaped_deps_dir//&/\\&}"
146148_escaped_home="${HOME//\\/\\\\}"
147149_escaped_home="${_escaped_home//&/\\&}"
148150_user_java_opts_placeholder='__JAVA_OPTS_BUILDPACK_PLACEHOLDER__'
149- _escaped_user_java_opts="${USER_JAVA_OPTS//\\/\\\\}"
150- _escaped_user_java_opts="${_escaped_user_java_opts//&/\\&}"
151151
152152if [ -d "$DEPS_DIR/%s/java_opts" ]; then
153153 for opts_file in "$DEPS_DIR/%s/java_opts"/*.opts; do
@@ -194,8 +194,21 @@ if [ -d "$DEPS_DIR/%s/java_opts" ]; then
194194 ;;
195195 esac
196196
197- # Now safely substitute JAVA_OPTS after expansion (preserves quotes, backslashes, and ampersands)
198- opts_content="${opts_content//$_user_java_opts_placeholder/$_escaped_user_java_opts}"
197+ # Restore USER_JAVA_OPTS via string-split, not ${//}: bash 4.x and 5.x
198+ # treat '\\' in replacement strings differently, corrupting backslashes.
199+ # %%%% / # are pure string ops — no special-char interpretation, any bash.
200+ # Pre-count occurrences so the loop is bounded even if USER_JAVA_OPTS
201+ # itself contained the placeholder string (infinite-loop defence).
202+ # Counting uses empty replacement — no backslash in replacement, safe.
203+ # Handles multiple occurrences (e.g. user config "$JAVA_OPTS -Xmx512m"
204+ # with from_environment:true produces "$JAVA_OPTS -Xmx512m $JAVA_OPTS").
205+ _stripped="${opts_content//"$_user_java_opts_placeholder"/}"
206+ _placeholder_count=$(( (${#opts_content} - ${#_stripped}) / ${#_user_java_opts_placeholder} ))
207+ for (( _i=0; _i<_placeholder_count; _i++ )); do
208+ _before="${opts_content%%%%"$_user_java_opts_placeholder"*}"
209+ _after="${opts_content#*"$_user_java_opts_placeholder"}"
210+ opts_content="${_before}${USER_JAVA_OPTS}${_after}"
211+ done
199212
200213 if [ -n "$opts_content" ]; then
201214 JAVA_OPTS="$JAVA_OPTS $opts_content"
0 commit comments