Skip to content

Commit da34a07

Browse files
committed
Remove restrictions from files that are included by pacman.conf
1 parent b8c3198 commit da34a07

3 files changed

Lines changed: 98 additions & 18 deletions

File tree

.golangci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ linters:
4141
gosec:
4242
excludes:
4343
- G104
44+
- G304
4445
formatters:
4546
enable:
4647
- gofumpt

internal/pacman/parser.go

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,24 @@ type Pacman struct {
2525
}
2626

2727
type parser struct {
28-
baseDir *os.Root
2928
includeFileCache map[string][]string
3029
}
3130

3231
func Parse(pacmanConfPath string) (*Pacman, error) {
33-
baseDir, err := os.OpenRoot(filepath.Dir(pacmanConfPath))
34-
if err != nil {
35-
return nil, err
36-
}
37-
38-
conf, err := newParser(baseDir).parseConfigFile(pacmanConfPath, defaultDBPath)
32+
conf, err := newParser().parseConfigFile(pacmanConfPath, defaultDBPath)
3933
if err != nil {
4034
return nil, err
4135
}
4236

4337
return &Pacman{config: conf}, nil
4438
}
4539

46-
func newParser(baseDir *os.Root) *parser {
40+
func newParser() *parser {
4741
return &parser{
48-
baseDir: baseDir,
4942
includeFileCache: make(map[string][]string),
5043
}
5144
}
5245

53-
func (parser *parser) openFile(name string) (*os.File, error) {
54-
fileName, ok := strings.CutPrefix(name, parser.baseDir.Name()+"/")
55-
if !ok {
56-
return nil, fmt.Errorf("filename %s is not relative to %s", name, parser.baseDir.Name())
57-
}
58-
return parser.baseDir.Open(fileName)
59-
}
60-
6146
func (parser *parser) parseConfigFile(configPath string, defaultDBPath string) (*config, error) {
6247
lines, err := parser.readConfigFile(configPath, 0)
6348
if err != nil {
@@ -84,7 +69,7 @@ func (parser *parser) readConfigFile(fileName string, depth int) ([]string, erro
8469
if depth >= configMaxRecursion {
8570
return nil, fmt.Errorf("reached maximum Include depth of %d", depth)
8671
}
87-
readFile, err := parser.openFile(fileName)
72+
readFile, err := os.Open(fileName)
8873
if err != nil {
8974
return nil, err
9075
}

tests/unit/internal/pacman/pacman_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,100 @@ func TestPacmanConfEmptySections(t *testing.T) {
185185
}
186186
}
187187

188+
func TestPacmanConfWithRelativePath(t *testing.T) {
189+
tempDir := t.TempDir()
190+
currentDir, err := os.Getwd()
191+
if err != nil {
192+
t.Fatal(err)
193+
}
194+
defer func() {
195+
if err := os.Chdir(currentDir); err != nil {
196+
t.Fatal(err)
197+
}
198+
}()
199+
200+
if err := os.Chdir(tempDir); err != nil {
201+
t.Fatal(err)
202+
}
203+
204+
if err := os.WriteFile("pacman.conf", fmt.Appendf(nil, "[core]\nServer=%s\n", MIRROR), 0o600); err != nil {
205+
t.Fatalf("Failed to create pacman.conf: %v", err)
206+
}
207+
208+
p, err := pacman.Parse("pacman.conf")
209+
if err != nil {
210+
t.Fatal(err)
211+
}
212+
out, err := p.GetServer()
213+
if err != nil {
214+
t.Fatal(err, out)
215+
}
216+
if out != SERVER {
217+
t.Error(out)
218+
}
219+
}
220+
221+
func TestPacmanConfWithIncludesInSubdirectory(t *testing.T) {
222+
tempDir := t.TempDir()
223+
pacmanConfFile := filepath.Join(tempDir, "pacman.conf")
224+
pacmanDDir := filepath.Join(tempDir, "pacman.d")
225+
226+
if err := os.Mkdir(pacmanDDir, 0o755); err != nil {
227+
t.Fatalf("Failed to create pacman.d directory: %v", err)
228+
}
229+
230+
mirrorlistFile := filepath.Join(pacmanDDir, "mirrorlist.local")
231+
if err := os.WriteFile(mirrorlistFile, fmt.Appendf(nil, "Server=%s\n", MIRROR), 0o600); err != nil {
232+
t.Fatalf("Failed to create mirrorlist: %v", err)
233+
}
234+
235+
if err := os.WriteFile(pacmanConfFile, fmt.Appendf(nil, "[core]\nInclude=%s\n", mirrorlistFile), 0o600); err != nil {
236+
t.Fatalf("Failed to create pacman.conf: %v", err)
237+
}
238+
239+
p, err := pacman.Parse(pacmanConfFile)
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
out, err := p.GetServer()
244+
if err != nil {
245+
t.Fatal(err, out)
246+
}
247+
if out != SERVER {
248+
t.Error(out)
249+
}
250+
}
251+
252+
func TestPacmanConfSymlink(t *testing.T) {
253+
tempDir := t.TempDir()
254+
realConfigDir := filepath.Join(tempDir, "real-location")
255+
if err := os.Mkdir(realConfigDir, 0o755); err != nil {
256+
t.Fatalf("Failed to create real config directory: %v", err)
257+
}
258+
259+
realConfigFile := filepath.Join(realConfigDir, "pacman.conf")
260+
if err := os.WriteFile(realConfigFile, fmt.Appendf(nil, "[core]\nServer=%s\n", MIRROR), 0o600); err != nil {
261+
t.Fatalf("Failed to create real pacman.conf: %v", err)
262+
}
263+
264+
symlinkFile := filepath.Join(tempDir, "pacman.conf")
265+
if err := os.Symlink(realConfigFile, symlinkFile); err != nil {
266+
t.Fatalf("Failed to create symlink: %v", err)
267+
}
268+
269+
p, err := pacman.Parse(symlinkFile)
270+
if err != nil {
271+
t.Fatal(err)
272+
}
273+
out, err := p.GetServer()
274+
if err != nil {
275+
t.Fatal(err, out)
276+
}
277+
if out != SERVER {
278+
t.Error(out)
279+
}
280+
}
281+
188282
func TestNormalizeMirrorUrl(t *testing.T) {
189283
tests := []struct {
190284
input string

0 commit comments

Comments
 (0)