Skip to content

Commit 799da57

Browse files
committed
Avoid overwriting malformed global config
1 parent ae1b932 commit 799da57

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/cli/__tests__/global-config.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ describe('global-config', () => {
106106
});
107107
});
108108

109+
it('does not overwrite malformed config', async () => {
110+
await writeFile(tmp.configFile, '{ invalid json');
111+
112+
const ok = await updateGlobalConfig({ telemetry: { enabled: true } }, tmp.configDir, tmp.configFile);
113+
114+
expect(ok).toBe(false);
115+
expect(await readFile(tmp.configFile, 'utf-8')).toBe('{ invalid json');
116+
});
117+
109118
it('returns false on write failures', async () => {
110119
const ok = await updateGlobalConfig(
111120
{ telemetry: { enabled: true } },

src/lib/schemas/io/global-config.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export async function updateGlobalConfig(
5252
configFile = GLOBAL_CONFIG_FILE
5353
): Promise<boolean> {
5454
try {
55-
const existing = await readGlobalConfig(configFile);
55+
const existing = await readGlobalConfigForUpdate(configFile);
5656
const merged: GlobalConfig = mergeConfig(existing, partial);
5757

5858
await mkdir(configDir, { recursive: true });
@@ -63,6 +63,18 @@ export async function updateGlobalConfig(
6363
}
6464
}
6565

66+
async function readGlobalConfigForUpdate(configFile: string): Promise<GlobalConfig> {
67+
try {
68+
const data = await readFile(configFile, 'utf-8');
69+
return GlobalConfigSchema.parse(JSON.parse(data));
70+
} catch (error) {
71+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
72+
return {};
73+
}
74+
throw error;
75+
}
76+
}
77+
6678
function mergeConfig(target: GlobalConfig, source: GlobalConfig): GlobalConfig {
6779
return {
6880
...target,

0 commit comments

Comments
 (0)