Skip to content

Commit

Permalink
fix: ignore zero or empty CRC and check file size (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorcafe authored Mar 12, 2024
1 parent f83948d commit 2140a68
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
12 changes: 9 additions & 3 deletions dat/dat.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type CRC uint32
type ROM struct {
XMLName xml.Name `xml:"rom"`
Name string `xml:"name,attr"`
Size int64 `xml:"size,attr"`
CRC CRC `xml:"crc,attr"`
}

Expand Down Expand Up @@ -63,7 +64,12 @@ func Parse(dat []byte) Dat {
}

// FindByCRC loops over the Dats in the DB and concurrently matches CRC checksums.
func (db *DB) FindByCRC(romPath string, romName string, crc uint32, games chan (Game)) {
func (db *DB) FindByCRC(romPath string, romName string, crc uint32, size int64, games chan (Game)) {
// skip empty file
if size == 0 || crc == 0 {
return
}

var wg sync.WaitGroup
wg.Add(len(*db))
// For every Dat in the DB
Expand All @@ -74,8 +80,8 @@ func (db *DB) FindByCRC(romPath string, romName string, crc uint32, games chan (
if len(game.ROMs) == 0 {
continue
}
// If the checksums match
if crc == uint32(game.ROMs[0].CRC) {
// If the checksums and sizes match
if crc == uint32(game.ROMs[0].CRC) && size == game.ROMs[0].Size {
game.Path = romPath
game.System = system
games <- game
Expand Down
17 changes: 12 additions & 5 deletions scanner/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"strconv"
"strings"

"github.com/libretro/ludo/dat"
ntf "github.com/libretro/ludo/notifications"
"github.com/libretro/ludo/playlists"
Expand Down Expand Up @@ -113,19 +114,20 @@ func Scan(dir string, roms []string, games chan (dat.Game), n *ntf.Notification)
}
for _, rom := range z.File {
romExt := filepath.Ext(rom.Name)
size := int64(rom.UncompressedSize64)
// these 4 systems might have headered or headerless roms and need special logic
if headerSize, ok := headerSizes[romExt]; ok {
crc, crcHeaderless, err := checksumHeaderless(rom, headerSize)
if err != nil {
n.Update(ntf.Error, err.Error())
continue
}
state.DB.FindByCRC(f, rom.Name, crc, games)
state.DB.FindByCRC(f, rom.Name, crcHeaderless, games)
state.DB.FindByCRC(f, rom.Name, crc, size, games)
state.DB.FindByCRC(f, rom.Name, crcHeaderless, size-int64(headerSize), games)
n.Update(ntf.Info, strconv.Itoa(i)+"/"+strconv.Itoa(len(roms))+" "+f)
} else if rom.CRC32 > 0 {
// Look for a matching game entry in the database
state.DB.FindByCRC(f, rom.Name, rom.CRC32, games)
state.DB.FindByCRC(f, rom.Name, rom.CRC32, size, games)
n.Update(ntf.Info, strconv.Itoa(i)+"/"+strconv.Itoa(len(roms))+" "+f)
}
}
Expand All @@ -140,11 +142,16 @@ func Scan(dir string, roms []string, games chan (dat.Game), n *ntf.Notification)
n.Update(ntf.Error, err.Error())
continue
}
s, err := os.Stat(f)
if err != nil {
n.Update(ntf.Error, err.Error())
continue
}
crc := crc32.ChecksumIEEE(bytes)
state.DB.FindByCRC(f, utils.FileName(f), crc, games)
state.DB.FindByCRC(f, utils.FileName(f), crc, s.Size(), games)
if headerSize, ok := headerSizes[ext]; ok {
crcHeaderless := crc32.ChecksumIEEE(bytes[headerSize:])
state.DB.FindByCRC(f, utils.FileName(f), crcHeaderless, games)
state.DB.FindByCRC(f, utils.FileName(f), crcHeaderless, s.Size()-int64(headerSize), games)
}
n.Update(ntf.Info, strconv.Itoa(i)+"/"+strconv.Itoa(len(roms))+" "+f)
}
Expand Down

0 comments on commit 2140a68

Please sign in to comment.