Skip to content

fix(apple): fix ENOBUFS when reading/writing plists #2443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions ios/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,15 @@ export function makeProject(projectRoot, targetPlatform, options, fs = nodefs) {
ReactTestAppUITests: project.uitestsBuildSettings,
};

const pbxproj = openXcodeProject(project.xcodeprojPath, fs);
const pbxproj = openXcodeProject(project.xcodeprojPath);
for (const target of pbxproj.targets) {
const { name: targetName } = target;
if (typeof targetName !== "string" || !(targetName in mods)) {
continue;
}

const targetBuildSettings = Object.entries(mods[targetName]);
for (const config of target.buildConfigurations) {
const { buildSettings } = config;
for (const { buildSettings } of target.buildConfigurations) {
assertObject(buildSettings, "target.buildConfigurations[].buildSettings");

for (const [setting, value] of targetBuildSettings) {
Expand Down
25 changes: 23 additions & 2 deletions ios/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { fileURLToPath } from "node:url";
* @typedef {import("../scripts/types.ts").JSONValue} JSONValue;
*/

const MAX_BUFFER = 16 * 1024 * 1024; // 16 MB because some plists can get big

/**
* @param {JSONValue} obj
* @returns {obj is JSONObject}
Expand Down Expand Up @@ -66,10 +68,11 @@ export function jsonFromPlist(filename) {
const args = ["-convert", "json", "-o", "-", filename];
const plutil = spawnSync("/usr/bin/plutil", args, {
stdio: ["ignore", "pipe", "inherit"],
maxBuffer: MAX_BUFFER,
});

if (plutil.status !== 0) {
throw new Error(`Failed to read '${filename}'`);
throw plutil.error ?? new Error(`Failed to read '${filename}'`);
}

return JSON.parse(plutil.stdout.toString());
Expand All @@ -85,10 +88,11 @@ export function plistFromJSON(source, filename) {
const plutil = spawnSync("/usr/bin/plutil", args, {
stdio: ["pipe", "pipe", "inherit"],
input: JSON.stringify(source),
maxBuffer: MAX_BUFFER,
});

if (plutil.status !== 0) {
throw new Error(`Failed to generate '${filename}'`);
throw plutil.error ?? new Error(`Failed to generate '${filename}'`);
}

return plutil.stdout.toString();
Expand Down Expand Up @@ -124,3 +128,20 @@ export function resolveResources(appConfig, targetPlatform) {

return undefined;
}

/**
* @param {string} destination
* @param {JSONObject} source
* @returns {void}
*/
export function writePlistFromJSON(destination, source) {
const args = ["-convert", "xml1", "-r", "-o", destination, "--", "-"];
const plutil = spawnSync("/usr/bin/plutil", args, {
stdio: ["pipe", "pipe", "inherit"],
input: JSON.stringify(source),
});

if (plutil.status !== 0) {
throw plutil.error ?? new Error(`Failed to write '${destination}'`);
}
}
6 changes: 3 additions & 3 deletions ios/xcode.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
isObject,
isString,
jsonFromPlist,
plistFromJSON,
writePlistFromJSON,
} from "./utils.mjs";

/**
Expand Down Expand Up @@ -227,7 +227,7 @@ export function configureBuildSchemes(
/**
* @param {string} xcodeproj
*/
export function openXcodeProject(xcodeproj, fs = nodefs) {
export function openXcodeProject(xcodeproj) {
const projectPath = path.join(xcodeproj, "project.pbxproj");
const pbxproj = jsonFromPlist(projectPath);
assertObject(pbxproj.objects, "pbxproj.objects");
Expand All @@ -242,7 +242,7 @@ export function openXcodeProject(xcodeproj, fs = nodefs) {

return {
save() {
fs.writeFileSync(projectPath, plistFromJSON(pbxproj, projectPath));
writePlistFromJSON(projectPath, pbxproj);
},
get targets() {
return targets.map((target, index) => {
Expand Down
Loading