fix: PE case-insensitive extensions (Win32/ISO 9660 compatibility) (#4996)

* fix: PE case-insensitive extensions (Win32/ISO 9660 compatibility)

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* expand cases to bpl files and surrounding catalogers

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Mike Zolotarov 2026-07-13 21:25:31 +02:00 committed by GitHub
parent 76ede661db
commit 987ae7f26a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 36 additions and 3 deletions

View File

@ -1055,6 +1055,9 @@ catalogers:
detector: # AUTO-GENERATED detector: # AUTO-GENERATED
method: glob # AUTO-GENERATED method: glob # AUTO-GENERATED
criteria: # AUTO-GENERATED criteria: # AUTO-GENERATED
- '**/*.DLL'
- '**/*.EXE'
- '**/*.BPL'
- '**/*.dll' - '**/*.dll'
- '**/*.exe' - '**/*.exe'
- '**/*.bpl' - '**/*.bpl'

View File

@ -16,7 +16,7 @@ import (
// BPL (Borland Package Library) files are PE-format binaries used by Delphi and C++Builder. // BPL (Borland Package Library) files are PE-format binaries used by Delphi and C++Builder.
func NewPEPackageCataloger() pkg.Cataloger { func NewPEPackageCataloger() pkg.Cataloger {
return generic.NewCataloger("pe-binary-package-cataloger"). return generic.NewCataloger("pe-binary-package-cataloger").
WithParserByGlobs(parsePE, "**/*.dll", "**/*.exe", "**/*.bpl") WithParserByGlobs(parsePE, "**/*.DLL", "**/*.EXE", "**/*.BPL", "**/*.dll", "**/*.exe", "**/*.bpl")
} }
func parsePE(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { func parsePE(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {

View File

@ -70,12 +70,16 @@ func Test_PEPackageCataloger_Globs(t *testing.T) {
expected []string expected []string
}{ }{
{ {
name: "obtain PE binary files (dll, exe, bpl)", name: "obtain PE binary files (dll, exe, bpl), including uppercase extensions",
fixture: "testdata/glob-paths", fixture: "testdata/glob-paths",
expected: []string{ expected: []string{
"src/library.dll", "src/library.dll",
"src/program.exe", "src/program.exe",
"src/archive.bpl", "src/archive.bpl",
// uppercase extensions appear on Windows/ISO 9660 filesystems and must also match
"src/winlibrary.DLL",
"src/winprogram.EXE",
"src/winarchive.BPL",
}, },
}, },
} }

View File

@ -0,0 +1 @@
bogus PE contents

View File

@ -0,0 +1 @@
bogus PE contents

View File

@ -0,0 +1 @@
bogus PE contents

View File

@ -39,6 +39,10 @@ catalogers:
- '**/*.deps.json' - '**/*.deps.json'
- '**/*.dll' - '**/*.dll'
- '**/*.exe' - '**/*.exe'
- '**/*.bpl'
- '**/*.DLL'
- '**/*.EXE'
- '**/*.BPL'
metadata_types: # AUTO-GENERATED metadata_types: # AUTO-GENERATED
- pkg.DotnetDepsEntry - pkg.DotnetDepsEntry
- pkg.DotnetPortableExecutableEntry - pkg.DotnetPortableExecutableEntry
@ -173,6 +177,10 @@ catalogers:
criteria: criteria:
- '**/*.dll' - '**/*.dll'
- '**/*.exe' - '**/*.exe'
- '**/*.bpl'
- '**/*.DLL'
- '**/*.EXE'
- '**/*.BPL'
metadata_types: # AUTO-GENERATED metadata_types: # AUTO-GENERATED
- pkg.DotnetPortableExecutableEntry - pkg.DotnetPortableExecutableEntry
package_types: # AUTO-GENERATED package_types: # AUTO-GENERATED

View File

@ -36,6 +36,10 @@ func TestCataloger_Globs(t *testing.T) {
"src/something.bpl", "src/something.bpl",
"src/something.dll", "src/something.dll",
"src/something.exe", "src/something.exe",
// uppercase extensions appear on Windows/ISO 9660 filesystems and must also match
"src/winsomething.DLL",
"src/winsomething.EXE",
"src/winsomething.BPL",
}, },
}, },
{ {
@ -47,6 +51,10 @@ func TestCataloger_Globs(t *testing.T) {
"src/something.deps.json", "src/something.deps.json",
"src/something.dll", "src/something.dll",
"src/something.exe", "src/something.exe",
// uppercase extensions appear on Windows/ISO 9660 filesystems and must also match
"src/winsomething.DLL",
"src/winsomething.EXE",
"src/winsomething.BPL",
}, },
// the binary cataloger probes executables by MIME type to find embedded bundles, // the binary cataloger probes executables by MIME type to find embedded bundles,
// but the glob fixtures aren't real binaries so those queries go unfulfilled // but the glob fixtures aren't real binaries so those queries go unfulfilled

View File

@ -27,6 +27,10 @@ const (
dllGlob = "**/*.dll" dllGlob = "**/*.dll"
exeGlob = "**/*.exe" exeGlob = "**/*.exe"
bplGlob = "**/*.bpl" bplGlob = "**/*.bpl"
// uppercase variants match PE files on case-preserving Windows/ISO 9660 filesystems (doublestar globs are case-sensitive)
dllGlobUpper = "**/*.DLL"
exeGlobUpper = "**/*.EXE"
bplGlobUpper = "**/*.BPL"
) )
var elfMagic = []byte{0x7f, 'E', 'L', 'F'} var elfMagic = []byte{0x7f, 'E', 'L', 'F'}
@ -483,7 +487,7 @@ func readDepsJSON(resolver file.Resolver, loc file.Location) (*depsJSON, error)
// findPEFiles locates and parses all PE files (dll/exe). // findPEFiles locates and parses all PE files (dll/exe).
func findPEFiles(resolver file.Resolver) ([]logicalPE, error, error) { func findPEFiles(resolver file.Resolver) ([]logicalPE, error, error) {
peLocs, err := resolver.FilesByGlob(dllGlob, exeGlob, bplGlob) peLocs, err := resolver.FilesByGlob(dllGlob, exeGlob, bplGlob, dllGlobUpper, exeGlobUpper, bplGlobUpper)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to find PE files: %w", err) return nil, nil, fmt.Errorf("unable to find PE files: %w", err)
} }

View File

@ -0,0 +1 @@
bogus PE contents

View File

@ -0,0 +1 @@
bogus PE contents

View File

@ -0,0 +1 @@
bogus PE contents