Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
# Test all supported versions on Linux (since it's fast)
matrix:
go: ['1.20', '1.21', '1.22', '1.23', '1.24']
go: ['1.21', '1.22', '1.23', '1.24', '1.25']
steps:
- uses: actions/checkout@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/charlievieth/fastwalk

go 1.20
go 1.21

retract v1.0.7 // Build broken on Go 1.20
25 changes: 25 additions & 0 deletions internal/dirent/dirent.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package dirent

import (
"encoding/binary"
"os"
"runtime"
"syscall"
Expand All @@ -11,6 +12,30 @@ import (

const InvalidMode = os.FileMode(1<<32 - 1)

// readInt returns the size-bytes unsigned integer in native byte order at offset off.
func readInt(b []byte, off, size uintptr) (uint64, bool) {
if len(b) < int(off+size) {
return 0, false
}
b = b[off:]
switch size {
case 1:
return uint64(b[0]), true
case 2:
return uint64(binary.NativeEndian.Uint16(b)), true
case 4:
return uint64(binary.NativeEndian.Uint32(b)), true
case 8:
return uint64(binary.NativeEndian.Uint64(b)), true
default:
// This case is impossible if the tests pass. Previously, we panicked
// here but for performance reasons (escape analysis) it's better to
// trigger a panic via an out-of-bounds reference.
_ = b[len(b)]
return 0, false
}
}

func Parse(buf []byte) (consumed int, name string, typ os.FileMode) {

reclen, ok := direntReclen(buf)
Expand Down
64 changes: 64 additions & 0 deletions internal/dirent/dirent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris

package dirent

import (
"encoding/binary"
"fmt"
"math"
"math/rand"
"testing"
)

func TestReadInt(t *testing.T) {
for _, sz := range []int{1, 2, 4, 8} {
rr := rand.New(rand.NewSource(1))
t.Run(fmt.Sprintf("%d", sz), func(t *testing.T) {
var fn func() uint64
switch sz {
case 1:
fn = func() uint64 { return uint64(rr.Int63n(256)) }
case 2:
fn = func() uint64 { return uint64(rr.Int63n(math.MaxUint16)) }
case 4:
fn = func() uint64 { return uint64(rr.Int63n(math.MaxUint32)) }
case 8:
fn = func() uint64 { return uint64(rr.Uint64()) }
default:
t.Fatal("invalid size:", sz)
}
buf := make([]byte, 8)
fails := 0
for i := 0; i < 100; i++ {
want := fn()
binary.NativeEndian.PutUint64(buf[:], want)
got, ok := readInt(buf, 0, uintptr(sz))
Comment on lines +34 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be the wrong spot; on big-endian, the PutUint64 will write non-zero to the ending bytes but the read is on the starting bytes.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thank you for pointing this out - will fix.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@QuLogic I created #65 to fix this issue and remove the offending test. Thank you again for reporting this!

if got != want || !ok {
fails++
t.Errorf("readInt(%q, 0, %d) = %d, %t; want: %d, %t", buf, sz, got, ok, want, true)
}
if fails >= 10 {
t.Fatal("too many errors:", fails)
}
}
})
}
if i, ok := readInt(nil, 1, 1); i != 0 || ok {
t.Errorf("readInt(nil, 1, 1) = %d, %t; want: %d, %t", i, ok, 0, false)
}
}

func TestReadIntSize(t *testing.T) {
if i, ok := readInt(nil, 1, 1); i != 0 || ok {
t.Errorf("readInt(nil, 1, 1) = %d, %t; want: %d, %t", i, ok, 0, false)
}
}

func TestReadIntInvalidSize(t *testing.T) {
defer func() {
if e := recover(); e == nil {
t.Errorf("Expected panic for invalid size")
}
}()
readInt(make([]byte, 32), 0, 9)
}
35 changes: 0 additions & 35 deletions internal/dirent/endian_big.go

This file was deleted.

7 changes: 0 additions & 7 deletions internal/dirent/endian_big_test.go

This file was deleted.

35 changes: 0 additions & 35 deletions internal/dirent/endian_little.go

This file was deleted.

7 changes: 0 additions & 7 deletions internal/dirent/endian_little_test.go

This file was deleted.

38 changes: 0 additions & 38 deletions internal/dirent/endian_test.go

This file was deleted.

Loading