STA-1598: Handle CRLF project headers during Codex config repair (#8197)

This commit is contained in:
Jinwoo Hong
2026-07-10 18:26:16 -07:00
committed by GitHub
parent 533992bdda
commit e6906d60a2
2 changed files with 69 additions and 1 deletions
@@ -334,6 +334,72 @@ describe('syncSystemConfigIntoManagedCodexHome', () => {
expect(runtimeConfig).toContain("[projects.'c:\\gemini_etl']")
})
it('deduplicates a CRLF system project header against an LF runtime header', () => {
mkdirSync(join(userDataDir, 'codex-runtime-home', 'home'), { recursive: true })
const projectHeader = '[projects."C:/Users/jinwo/orca/workspaces/orca/repo"]'
writeFileSync(
getRuntimeConfigPath(),
[projectHeader, 'trust_level = "trusted"', ''].join('\n'),
'utf-8'
)
writeFileSync(
getSystemConfigPath(),
[projectHeader, 'trust_level = "trusted"', ''].join('\r\n'),
'utf-8'
)
syncSystemConfigIntoManagedCodexHome()
const runtimeConfig = readFileSync(getRuntimeConfigPath(), 'utf-8')
expect(runtimeConfig.match(/\[projects\./g)).toHaveLength(1)
expect(runtimeConfig).toContain(`${projectHeader}\ntrust_level = "trusted"`)
})
it('self-heals duplicate project tables in a CRLF runtime config', () => {
mkdirSync(join(userDataDir, 'codex-runtime-home', 'home'), { recursive: true })
const projectHeader = '[projects."C:/Users/jinwo/orca/workspaces/orca/repo"]'
writeFileSync(
getRuntimeConfigPath(),
[
projectHeader,
'trust_level = "trusted"',
'',
projectHeader,
'trust_level = "trusted"',
''
].join('\r\n'),
'utf-8'
)
writeFileSync(getSystemConfigPath(), 'model = "gpt-5"\n', 'utf-8')
syncSystemConfigIntoManagedCodexHome()
const runtimeConfig = readFileSync(getRuntimeConfigPath(), 'utf-8')
expect(runtimeConfig.match(/\[projects\./g)).toHaveLength(1)
expect(runtimeConfig).toContain('trust_level = "trusted"')
})
it('applies a CRLF system revocation to an LF runtime project', () => {
mkdirSync(join(userDataDir, 'codex-runtime-home', 'home'), { recursive: true })
writeFileSync(
getRuntimeConfigPath(),
["[projects.'c:\\repo']", 'trust_level = "trusted"', ''].join('\n'),
'utf-8'
)
writeFileSync(
getSystemConfigPath(),
['[projects."C:/repo"]', 'trust_level = "untrusted"', ''].join('\r\n'),
'utf-8'
)
syncSystemConfigIntoManagedCodexHome()
const runtimeConfig = readFileSync(getRuntimeConfigPath(), 'utf-8')
expect(runtimeConfig.match(/\[projects\./g)).toHaveLength(1)
expect(runtimeConfig).toContain('trust_level = "untrusted"')
expect(runtimeConfig).not.toContain('trust_level = "trusted"')
})
it('lets a semantically matching system revocation replace runtime trust', () => {
mkdirSync(join(userDataDir, 'codex-runtime-home', 'home'), { recursive: true })
writeFileSync(
+3 -1
View File
@@ -591,7 +591,9 @@ function parseHookStateHeaderKey(line: string): string | null {
}
export function parseCodexProjectHeaderPath(line: string): string | null {
const trimmed = line.trimStart()
// Why: mirror section headers come from split CRLF files and retain the
// terminal carriage return, while direct upserts scan CR-stripped lines.
const trimmed = line.replace(/\r$/, '').trimStart()
const prefixMatch = /^\[[ \t]*projects[ \t]*\.[ \t]*/.exec(trimmed)
if (!prefixMatch) {
return null