From 8e2d2c8246409dca96cee8589c0d841ef878d802 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Fri, 14 Nov 2025 18:32:47 +0900 Subject: [PATCH] ldd: check decoder scan guard This was unreachable via the Parse wrapper. Signed-off-by: Ophestra --- ldd/ldd.go | 30 +++++++++++++++--------------- ldd/ldd_test.go | 23 +++++++++++++++++++---- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/ldd/ldd.go b/ldd/ldd.go index 9611c7b..7b88e69 100644 --- a/ldd/ldd.go +++ b/ldd/ldd.go @@ -44,21 +44,6 @@ type Entry struct { Location uint64 `json:"location"` } -// Path returns a deduplicated slice of absolute directory paths in entries. -func Path(entries []*Entry) []*check.Absolute { - p := make([]*check.Absolute, 0, len(entries)*2) - for _, entry := range entries { - if entry.Path != nil { - p = append(p, entry.Path.Dir()) - } - if a, err := check.NewAbs(entry.Name); err == nil { - p = append(p, a.Dir()) - } - } - check.SortAbs(p) - return check.CompactAbs(p) -} - const ( // entrySegmentIndexName is the index of the segment holding [Entry.Name]. entrySegmentIndexName = 0 @@ -132,6 +117,21 @@ func (e *Entry) UnmarshalText(data []byte) error { return e.decodeLocationSegment(segments[iL]) } +// Path returns a deduplicated slice of absolute directory paths in entries. +func Path(entries []*Entry) []*check.Absolute { + p := make([]*check.Absolute, 0, len(entries)*2) + for _, entry := range entries { + if entry.Path != nil { + p = append(p, entry.Path.Dir()) + } + if a, err := check.NewAbs(entry.Name); err == nil { + p = append(p, a.Dir()) + } + } + check.SortAbs(p) + return check.CompactAbs(p) +} + // A Decoder reads and decodes [Entry] values from an input stream. // // The zero value is not safe for use. diff --git a/ldd/ldd_test.go b/ldd/ldd_test.go index 0288a7c..2bacb7a 100644 --- a/ldd/ldd_test.go +++ b/ldd/ldd_test.go @@ -2,15 +2,22 @@ package ldd_test import ( "encoding/json" - "errors" "reflect" + "strings" "testing" "hakurei.app/container/check" "hakurei.app/ldd" ) -func TestParseError(t *testing.T) { +func TestEntryUnexpectedSegmentsError(t *testing.T) { + const want = `unexpected segments in entry "\x00"` + if got := ldd.EntryUnexpectedSegmentsError("\x00").Error(); got != want { + t.Fatalf("Error: %s, want %s", got, want) + } +} + +func TestDecodeError(t *testing.T) { t.Parallel() testCases := []struct { @@ -38,12 +45,20 @@ meow libzstd.so.1 => /usr/lib/libzstd.so.1 (0x7ff71bfd2000) {"bad location format", ` libzstd.so.1 => /usr/lib/libzstd.so.1 7ff71bfd2000 `, ldd.ErrBadLocationFormat}, + + {"valid", ``, nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Parallel() - if _, err := ldd.Parse([]byte(tc.out)); !errors.Is(err, tc.wantErr) { - t.Errorf("Parse() error = %v, wantErr %v", err, tc.wantErr) + + d := ldd.NewDecoder(strings.NewReader(tc.out)) + + if _, err := d.Decode(); !reflect.DeepEqual(err, tc.wantErr) { + t.Errorf("Decode: error = %v, wantErr %v", err, tc.wantErr) + } + if d.Scan(new(ldd.Entry)) { + t.Fatalf("Scan: unexpected true") } }) }