From 3fcce094674ba473bf9b0230170a778a9ec74a2f Mon Sep 17 00:00:00 2001 From: Bjormg Date: Fri, 24 Jul 2026 15:11:05 +0700 Subject: [PATCH 1/2] fix: execFileSync shell command built from environment values Use `execFileSync` (or `spawn` with argument arrays) instead of `execSync` with a command string, so file paths are passed as literal arguments and never interpreted by a shell. Best single fix in `apps/expo-app/scripts/utils/AndroidBuilder.mjs`: - Update the child_process import to include `execFileSync` and remove `execSync` usage. - Replace all three `execSync(...)` invocations in `applyBundle` with `execFileSync(binary, args, options)`. - Keep existing behavior (`cwd`, `stdio: 'inherit'`) unchanged. This addresses both alert variants at once because both tainted paths are no longer concatenated into a shell command string. --- apps/expo-app/scripts/utils/AndroidBuilder.mjs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/expo-app/scripts/utils/AndroidBuilder.mjs b/apps/expo-app/scripts/utils/AndroidBuilder.mjs index 7195137b56..0fdbd8c65b 100644 --- a/apps/expo-app/scripts/utils/AndroidBuilder.mjs +++ b/apps/expo-app/scripts/utils/AndroidBuilder.mjs @@ -1,4 +1,4 @@ -import { execSync, spawn } from 'node:child_process'; +import { execFileSync, spawn } from 'node:child_process'; import fs from 'node:fs/promises'; import path from 'node:path'; @@ -183,15 +183,16 @@ android.buildTypes.release.shrinkResources = true // Replace assets/index.android.bundle in the APK (cd into patchDir so zip path is correct) console.log(`\nPatching bundle into APK: ${apk}...`); - execSync(`zip -u ${apk} assets/index.android.bundle`, { cwd: patchDir, stdio: 'inherit' }); + execFileSync('zip', ['-u', apk, 'assets/index.android.bundle'], { cwd: patchDir, stdio: 'inherit' }); // Re-align (zip modification breaks alignment) then re-sign with debug keystore - execSync(`zipalign -f 4 ${apk} ${alignedApk}`, { stdio: 'inherit' }); + execFileSync('zipalign', ['-f', '4', apk, alignedApk], { stdio: 'inherit' }); await fs.rename(alignedApk, apk); const debugKeystore = path.resolve(process.env.HOME, '.android/debug.keystore'); - execSync( - `apksigner sign --ks ${debugKeystore} --ks-pass pass:android --key-pass pass:android ${apk}`, + execFileSync( + 'apksigner', + ['sign', '--ks', debugKeystore, '--ks-pass', 'pass:android', '--key-pass', 'pass:android', apk], { stdio: 'inherit' }, ); From 36f80a1b2307428db70edbc47ae539c997384822 Mon Sep 17 00:00:00 2001 From: Bjormg Date: Fri, 24 Jul 2026 08:20:51 +0000 Subject: [PATCH 2/2] fix: resolve fixes execSync Shell command values --- packages/mobile-visreg/src/upload.mjs | 4 ++-- tools/generateTarballs.mjs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mobile-visreg/src/upload.mjs b/packages/mobile-visreg/src/upload.mjs index c17cf66f45..53415f178c 100644 --- a/packages/mobile-visreg/src/upload.mjs +++ b/packages/mobile-visreg/src/upload.mjs @@ -1,4 +1,4 @@ -import { execSync } from 'child_process'; +import { execFileSync } from 'child_process'; import { resolve } from 'path'; function parseArgs() { @@ -24,6 +24,6 @@ if (!process.env.PERCY_TOKEN) { const screenshotDir = resolve(dir); console.log(`Uploading screenshots from ${screenshotDir} to Percy...`); -execSync(`npx percy upload ${screenshotDir}`, { stdio: 'inherit' }); +execFileSync('npx', ['percy', 'upload', screenshotDir], { stdio: 'inherit' }); console.log('\nUpload complete. Visit percy.io to review the build.'); diff --git a/tools/generateTarballs.mjs b/tools/generateTarballs.mjs index 7d72e0032c..9b412689e5 100644 --- a/tools/generateTarballs.mjs +++ b/tools/generateTarballs.mjs @@ -1,4 +1,4 @@ -import { execSync } from 'child_process'; +import { execFileSync, execSync } from 'child_process'; import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync } from 'fs'; import inquirer from 'inquirer'; import { join, resolve } from 'path'; @@ -106,7 +106,7 @@ async function main() { const tarballPath = resolve(tarballsDir, tarballName); process.chdir(projectDir); - execSync(`yarn pack --filename ${tarballPath}`, { + execFileSync('yarn', ['pack', '--filename', tarballPath], { maxBuffer: 1024 * 1024 * 10, // 10MB buffer stdio: 'pipe', });