fix(review): harden CEF init trace log setup
- commit
- 62cb26b869a6eb1b6e75b3b67e100e72d3b1fa9c
- author
- brice · · 2026-04-19 10:07 UTC
- parent
- 2b89483
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +41 -1
M internal/infrastructure/cef/engine_init.go +6 -1
| @@ -486,7 +486,12 @@ func prepareCEFInitTraceFile(defaultLogFile, logFile string) (string, error) { | |||
| 486 | 486 | if err := os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm); err != nil { | |
| 487 | 487 | return "", fmt.Errorf("mkdir %s: %w", filepath.Dir(bootstrapLogFile), err) | |
| 488 | 488 | } | |
| 489 | - | if err := os.WriteFile(bootstrapLogFile, nil, filePerm); err != nil { | |
| 489 | + | file, err := openRegularLogFile(bootstrapLogFile) | |
| 490 | + | if err != nil { | |
| 491 | + | return "", fmt.Errorf("reset %s: %w", bootstrapLogFile, err) | |
| 492 | + | } | |
| 493 | + | defer func() { _ = file.Close() }() | |
| 494 | + | if err := file.Truncate(0); err != nil { | |
| 490 | 495 | return "", fmt.Errorf("reset %s: %w", bootstrapLogFile, err) | |
| 491 | 496 | } | |
| 492 | 497 | return bootstrapLogFile, nil | |
| @@ -486,7 +486,12 @@ func prepareCEFInitTraceFile(defaultLogFile, logFile string) (string, error) { | |||||
| 486 | if err := os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm); err != nil { | 486 | if err := os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm); err != nil { | ||
| 487 | return "", fmt.Errorf("mkdir %s: %w", filepath.Dir(bootstrapLogFile), err) | 487 | return "", fmt.Errorf("mkdir %s: %w", filepath.Dir(bootstrapLogFile), err) | ||
| 488 | } | 488 | } | ||
| 489 | - | if err := os.WriteFile(bootstrapLogFile, nil, filePerm); err != nil { | 489 | + | file, err := openRegularLogFile(bootstrapLogFile) |
| 490 | + | if err != nil { | |||
| 491 | + | return "", fmt.Errorf("reset %s: %w", bootstrapLogFile, err) | |||
| 492 | + | } | |||
| 493 | + | defer func() { _ = file.Close() }() | |||
| 494 | + | if err := file.Truncate(0); err != nil { | |||
| 490 | return "", fmt.Errorf("reset %s: %w", bootstrapLogFile, err) | 495 | return "", fmt.Errorf("reset %s: %w", bootstrapLogFile, err) | ||
| 491 | } | 496 | } | ||
| 492 | return bootstrapLogFile, nil | 497 | return bootstrapLogFile, nil | ||
M internal/infrastructure/cef/engine_init_test.go +35 -0
| @@ -142,6 +142,41 @@ func TestPrepareCEFInitTraceFile_EnabledViaExplicitLogFile(t *testing.T) { | |||
| 142 | 142 | require.Equal(t, os.FileMode(dirPerm), dirInfo.Mode().Perm()) | |
| 143 | 143 | } | |
| 144 | 144 | ||
| 145 | + | func TestPrepareCEFInitTraceFile_TruncatesExistingFile(t *testing.T) { | |
| 146 | + | t.Setenv(puregoCEFInitTraceEnvVar, "1") | |
| 147 | + | logFile := filepath.Join(t.TempDir(), "custom", "cef_runtime.log") | |
| 148 | + | bootstrapLogFile := filepath.Join(filepath.Dir(logFile), "cef_runtime.bootstrap.log") | |
| 149 | + | require.NoError(t, os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm)) | |
| 150 | + | require.NoError(t, os.WriteFile(bootstrapLogFile, []byte("existing"), filePerm)) | |
| 151 | + | ||
| 152 | + | path, err := prepareCEFInitTraceFile("", logFile) | |
| 153 | + | require.NoError(t, err) | |
| 154 | + | require.Equal(t, bootstrapLogFile, path) | |
| 155 | + | ||
| 156 | + | content, readErr := os.ReadFile(path) | |
| 157 | + | require.NoError(t, readErr) | |
| 158 | + | require.Empty(t, content) | |
| 159 | + | } | |
| 160 | + | ||
| 161 | + | func TestPrepareCEFInitTraceFile_RejectsSymlink(t *testing.T) { | |
| 162 | + | t.Setenv(puregoCEFInitTraceEnvVar, "1") | |
| 163 | + | target := filepath.Join(t.TempDir(), "target.bootstrap.log") | |
| 164 | + | require.NoError(t, os.WriteFile(target, []byte("existing"), 0o644)) | |
| 165 | + | ||
| 166 | + | logFile := filepath.Join(t.TempDir(), "custom", "cef_runtime.log") | |
| 167 | + | bootstrapLogFile := filepath.Join(filepath.Dir(logFile), "cef_runtime.bootstrap.log") | |
| 168 | + | require.NoError(t, os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm)) | |
| 169 | + | require.NoError(t, os.Symlink(target, bootstrapLogFile)) | |
| 170 | + | ||
| 171 | + | path, err := prepareCEFInitTraceFile("", logFile) | |
| 172 | + | require.ErrorContains(t, err, "must not be a symlink") | |
| 173 | + | require.Empty(t, path) | |
| 174 | + | ||
| 175 | + | targetInfo, statErr := os.Stat(target) | |
| 176 | + | require.NoError(t, statErr) | |
| 177 | + | require.Equal(t, os.FileMode(0o644), targetInfo.Mode().Perm()) | |
| 178 | + | } | |
| 179 | + | ||
| 145 | 180 | func TestPrepareCEFInitTraceFile_UsesResolvedProfileLogDirByDefault(t *testing.T) { | |
| 146 | 181 | t.Setenv(puregoCEFInitTraceEnvVar, "1") | |
| 147 | 182 | profile := testCEFDevProfile(t) | |
| @@ -142,6 +142,41 @@ func TestPrepareCEFInitTraceFile_EnabledViaExplicitLogFile(t *testing.T) { | |||||
| 142 | require.Equal(t, os.FileMode(dirPerm), dirInfo.Mode().Perm()) | 142 | require.Equal(t, os.FileMode(dirPerm), dirInfo.Mode().Perm()) | ||
| 143 | } | 143 | } | ||
| 144 | 144 | ||||
| 145 | + | func TestPrepareCEFInitTraceFile_TruncatesExistingFile(t *testing.T) { | |||
| 146 | + | t.Setenv(puregoCEFInitTraceEnvVar, "1") | |||
| 147 | + | logFile := filepath.Join(t.TempDir(), "custom", "cef_runtime.log") | |||
| 148 | + | bootstrapLogFile := filepath.Join(filepath.Dir(logFile), "cef_runtime.bootstrap.log") | |||
| 149 | + | require.NoError(t, os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm)) | |||
| 150 | + | require.NoError(t, os.WriteFile(bootstrapLogFile, []byte("existing"), filePerm)) | |||
| 151 | + | ||||
| 152 | + | path, err := prepareCEFInitTraceFile("", logFile) | |||
| 153 | + | require.NoError(t, err) | |||
| 154 | + | require.Equal(t, bootstrapLogFile, path) | |||
| 155 | + | ||||
| 156 | + | content, readErr := os.ReadFile(path) | |||
| 157 | + | require.NoError(t, readErr) | |||
| 158 | + | require.Empty(t, content) | |||
| 159 | + | } | |||
| 160 | + | ||||
| 161 | + | func TestPrepareCEFInitTraceFile_RejectsSymlink(t *testing.T) { | |||
| 162 | + | t.Setenv(puregoCEFInitTraceEnvVar, "1") | |||
| 163 | + | target := filepath.Join(t.TempDir(), "target.bootstrap.log") | |||
| 164 | + | require.NoError(t, os.WriteFile(target, []byte("existing"), 0o644)) | |||
| 165 | + | ||||
| 166 | + | logFile := filepath.Join(t.TempDir(), "custom", "cef_runtime.log") | |||
| 167 | + | bootstrapLogFile := filepath.Join(filepath.Dir(logFile), "cef_runtime.bootstrap.log") | |||
| 168 | + | require.NoError(t, os.MkdirAll(filepath.Dir(bootstrapLogFile), dirPerm)) | |||
| 169 | + | require.NoError(t, os.Symlink(target, bootstrapLogFile)) | |||
| 170 | + | ||||
| 171 | + | path, err := prepareCEFInitTraceFile("", logFile) | |||
| 172 | + | require.ErrorContains(t, err, "must not be a symlink") | |||
| 173 | + | require.Empty(t, path) | |||
| 174 | + | ||||
| 175 | + | targetInfo, statErr := os.Stat(target) | |||
| 176 | + | require.NoError(t, statErr) | |||
| 177 | + | require.Equal(t, os.FileMode(0o644), targetInfo.Mode().Perm()) | |||
| 178 | + | } | |||
| 179 | + | ||||
| 145 | func TestPrepareCEFInitTraceFile_UsesResolvedProfileLogDirByDefault(t *testing.T) { | 180 | func TestPrepareCEFInitTraceFile_UsesResolvedProfileLogDirByDefault(t *testing.T) { | ||
| 146 | t.Setenv(puregoCEFInitTraceEnvVar, "1") | 181 | t.Setenv(puregoCEFInitTraceEnvVar, "1") | ||
| 147 | profile := testCEFDevProfile(t) | 182 | profile := testCEFDevProfile(t) | ||