Skip to content

Commit b28e68e

Browse files
committed
fix(macos): validate DMG layout values
1 parent 5d1e649 commit b28e68e

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

scripts/create-dmg.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,46 @@ DMG_APP_POS="${DMG_APP_POS:-125 160}"
4949
DMG_APPS_POS="${DMG_APPS_POS:-375 160}"
5050
DMG_EXTRA_SECTORS="${DMG_EXTRA_SECTORS:-2048}"
5151

52+
require_integer_list() {
53+
local name="$1"
54+
local raw="$2"
55+
local expected_count="$3"
56+
local values=()
57+
local value
58+
59+
if [[ "$raw" == *$'\n'* || "$raw" == *$'\r'* ]]; then
60+
echo "Error: $name must be a single line of integer values: '$raw'" >&2
61+
exit 1
62+
fi
63+
64+
read -r -a values <<< "$raw"
65+
if [[ "${#values[@]}" -ne "$expected_count" ]]; then
66+
echo "Error: $name must contain $expected_count integer value(s): '$raw'" >&2
67+
exit 1
68+
fi
69+
70+
for value in "${values[@]}"; do
71+
if [[ ! "$value" =~ ^-?[0-9]+$ ]]; then
72+
echo "Error: $name must contain only integer values: '$raw'" >&2
73+
exit 1
74+
fi
75+
done
76+
}
77+
78+
require_positive_integer() {
79+
local name="$1"
80+
local raw="$2"
81+
if [[ ! "$raw" =~ ^[1-9][0-9]*$ ]]; then
82+
echo "Error: $name must be a positive integer: '$raw'" >&2
83+
exit 1
84+
fi
85+
}
86+
87+
require_integer_list DMG_WINDOW_BOUNDS "$DMG_WINDOW_BOUNDS" 4
88+
require_integer_list DMG_APP_POS "$DMG_APP_POS" 2
89+
require_integer_list DMG_APPS_POS "$DMG_APPS_POS" 2
90+
require_positive_integer DMG_ICON_SIZE "$DMG_ICON_SIZE"
91+
5292
to_applescript_list4() {
5393
local raw="$1"
5494
echo "$raw" | awk '{ printf "%s, %s, %s, %s", $1, $2, $3, $4 }'

test/scripts/create-dmg.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,42 @@ describe.runIf(process.platform === "darwin")("create-dmg ownership boundaries",
265265
expect(readFileSync(tools.hdiutilLog, "utf8")).not.toContain("detach");
266266
});
267267

268+
it("fails before image creation when Finder layout values are malformed", () => {
269+
const app = makeValidApp();
270+
const outputDir = mkdtempSync(path.join(tmpdir(), "openclaw-create-dmg-output-"));
271+
tempDirs.push(outputDir);
272+
const output = path.join(outputDir, "OpenClaw.dmg");
273+
const tools = makeFakeDmgTools();
274+
275+
const result = runScript([app, output], {
276+
...tools.env,
277+
DMG_WINDOW_BOUNDS: "400 nope 900 420",
278+
});
279+
280+
expect(result.status).toBe(1);
281+
expect(result.stderr).toContain("DMG_WINDOW_BOUNDS must contain only integer values");
282+
expect(existsSync(output)).toBe(false);
283+
expect(existsSync(tools.hdiutilLog) ? readFileSync(tools.hdiutilLog, "utf8") : "").toBe("");
284+
});
285+
286+
it("fails before image creation when Finder layout values span multiple lines", () => {
287+
const app = makeValidApp();
288+
const outputDir = mkdtempSync(path.join(tmpdir(), "openclaw-create-dmg-output-"));
289+
tempDirs.push(outputDir);
290+
const output = path.join(outputDir, "OpenClaw.dmg");
291+
const tools = makeFakeDmgTools();
292+
293+
const result = runScript([app, output], {
294+
...tools.env,
295+
DMG_WINDOW_BOUNDS: "400 100 900 420\nnope",
296+
});
297+
298+
expect(result.status).toBe(1);
299+
expect(result.stderr).toContain("DMG_WINDOW_BOUNDS must be a single line");
300+
expect(existsSync(output)).toBe(false);
301+
expect(existsSync(tools.hdiutilLog) ? readFileSync(tools.hdiutilLog, "utf8") : "").toBe("");
302+
});
303+
268304
it("preserves an existing output when verification fails", () => {
269305
const app = makeValidApp();
270306
const outputDir = mkdtempSync(path.join(tmpdir(), "openclaw-create-dmg-output-"));

0 commit comments

Comments
 (0)