Skip to content

Commit 1baaca1

Browse files
author
ImageManager Bot
committed
fix(build): template ARG substitution handles spaces, ${refs} and special chars
The 'Apply template values' step rejected any ARG value outside a narrow char allowlist (no spaces/$/{/}), so legitimate configure-style values like LUSTRE_CONFIG_ARGS="--with-linux=...${LINUX_KERNEL}... --disable-tests ..." failed the build. And the unquoted sed replacement would have broken Docker's ARG parsing for multi-word values anyway. Rewrote it in Python as a literal file edit: validates ARG names are identifiers and values have no newline, then writes ARG NAME="value" (double-quoted, ${OTHER_ARG} preserved for build-time expansion). No sed/shell interpolation -> no injection via #/&/quotes/spaces.
1 parent 7b2d267 commit 1baaca1

1 file changed

Lines changed: 41 additions & 15 deletions

File tree

.github/workflows/reusable-build.yml

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,51 @@ jobs:
115115
echo "Template values: $TEMPLATE_VALUES_JSON"
116116
cp "$DOCKERFILE_PATH" "$DOCKERFILE_PATH.original"
117117
118-
# Parse and rewrite ARG lines. Both name and value go through a
119-
# strict char allowlist (matches the backend validator). Anything
120-
# the allowlist rejects fails the build immediately.
121-
while IFS=$'\t' read -r arg_name arg_value; do
122-
[ -z "$arg_name" ] && continue
123-
if ! [[ "$arg_name" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
124-
echo "Refusing to substitute non-identifier ARG name: $arg_name"; exit 1
125-
fi
126-
if ! [[ "$arg_value" =~ ^[A-Za-z0-9._+:/=,-]+$ ]]; then
127-
echo "Refusing unsafe ARG value for $arg_name"; exit 1
128-
fi
129-
echo "Replacing ARG $arg_name with value: $arg_value"
130-
sed -i "s#^ARG ${arg_name}=.*#ARG ${arg_name}=${arg_value}#g" "$DOCKERFILE_PATH"
131-
done < <(jq -r 'to_entries[] | "\(.key)\t\(.value)"' <<<"$TEMPLATE_VALUES_JSON")
118+
# Rewrite each templated `ARG NAME=...` line with its value. Done in
119+
# Python as a literal file edit — no sed/shell interpolation (so a `#`,
120+
# `&`, space or quote in the value can't break the substitution) and no
121+
# over-strict char allowlist (configure-style flags with spaces and
122+
# ${OTHER_ARG} refs are legitimate). Names must be ARG identifiers;
123+
# values may be anything except a newline (which could inject a
124+
# Dockerfile instruction). The value is double-quoted so it survives
125+
# Docker's ARG parsing; ${...} is preserved for build-time expansion.
126+
python3 - <<'PY'
127+
import json, os, re, sys
128+
vals = json.loads(os.environ["TEMPLATE_VALUES_JSON"])
129+
path = os.environ["DOCKERFILE_PATH"]
130+
ident = re.compile(r'^[A-Za-z_][A-Za-z0-9_]*$')
131+
for k in list(vals):
132+
v = vals[k] if isinstance(vals[k], str) else str(vals[k])
133+
if not ident.match(k):
134+
print(f"Refusing non-identifier ARG name: {k}"); sys.exit(1)
135+
if '\n' in v or '\r' in v:
136+
print(f"Refusing ARG value with a newline: {k}"); sys.exit(1)
137+
vals[k] = v
138+
arg_re = re.compile(r'^(\s*ARG\s+)([A-Za-z_][A-Za-z0-9_]*)\s*=.*$')
139+
replaced, out = set(), []
140+
with open(path) as f:
141+
for line in f:
142+
nl = '\n' if line.endswith('\n') else ''
143+
m = arg_re.match(line.rstrip('\n'))
144+
if m and m.group(2) in vals:
145+
name = m.group(2)
146+
q = '"' + vals[name].replace('\\', '\\\\').replace('"', '\\"') + '"'
147+
out.append(f'{m.group(1)}{name}={q}{nl}')
148+
print(f"Replacing ARG {name} -> {q}")
149+
replaced.add(name)
150+
else:
151+
out.append(line)
152+
with open(path, 'w') as f:
153+
f.writelines(out)
154+
miss = sorted(set(vals) - replaced)
155+
if miss:
156+
print(f"Template keys with no matching 'ARG NAME=' line (left as-is): {miss}")
157+
PY
132158
133159
echo "Dockerfile modifications completed"
134160
echo ""
135161
echo "=== Modified ARG lines ==="
136-
grep "^ARG" "$DOCKERFILE_PATH" || echo "No ARG lines found"
162+
grep -nE "^[[:space:]]*ARG[[:space:]]" "$DOCKERFILE_PATH" || echo "No ARG lines found"
137163
echo "=========================="
138164
139165
- name: Configure podman environment

0 commit comments

Comments
 (0)