v0.12.3 — Security & correctness bug fixes (33 bugs)
CRITICAL: 10 data race and security fixes — backup.go mutex coverage (C1-C4), IsSystemDisk 12-bit major/minor (C5), /dev/ path validation (C6), extractName traversal (C7), TargetPath/DestinationPath against registered paths (C8-C9), ParseComposeHDDMounts Clean-before-prefix (C10). HIGH: 17 logic/resource fixes — ValidateDump bufio.Scanner (H1), single appDirSize() with 30s timeout (H2/H3), snapshot ID regex (H4), cross-drive restic prune (H5), temp file order (H6), dirSizeBytes errors (H7), atomic fstab (H8), IsDeviceMounted suffix check (H9), eMMC partition mapping (H10), bytesCopied mutex (H11), separator-aware migrate prefix (H13), DeleteStack error on compose-down (H14), docker 60s timeout (H16), NotificationPrefs deep-copy (H17), wipefs warning (H18), fstab rollback on mount fail (H19). MEDIUM: 7 code quality fixes — formatBytes dedup (M1), .tmp filter order (M2), sizeBytes string type (M3), elapsed in message (M6), LoadLocation fallback (M7), pathCovers separator (M10), cancelEditLabel textContent (M11). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,10 @@ func (d *lsblkDevice) sizeBytes() int64 {
|
||||
switch v := d.Size.(type) {
|
||||
case float64:
|
||||
return int64(v)
|
||||
case string:
|
||||
// M3: lsblk can return size as a string on some kernel versions.
|
||||
n, _ := strconv.ParseUint(v, 10, 64)
|
||||
return int64(n)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -157,18 +161,29 @@ func getSystemDiskNames() map[string]bool {
|
||||
}
|
||||
|
||||
// partitionToParentDisk extracts the parent disk name from a partition device path.
|
||||
// "/dev/sda2" → "sda", "/dev/nvme0n1p2" → "nvme0n1"
|
||||
// "/dev/sda2" → "sda", "/dev/nvme0n1p2" → "nvme0n1", "/dev/mmcblk0p1" → "mmcblk0"
|
||||
func partitionToParentDisk(devPath string) string {
|
||||
name := filepath.Base(devPath)
|
||||
|
||||
// NVMe: nvme0n1p2 → nvme0n1
|
||||
if strings.Contains(name, "nvme") {
|
||||
if idx := strings.LastIndex(name, "p"); idx > 0 {
|
||||
if _, err := strconv.Atoi(name[idx+1:]); err == nil {
|
||||
return name[:idx]
|
||||
// H10: Handle mmcblk0p1 and nvme0n1p1 patterns where 'p' separates disk# from partition#.
|
||||
// The prefix before 'p' must end with a digit (e.g., mmcblk0, nvme0n1) to be a disk number.
|
||||
if idx := strings.LastIndex(name, "p"); idx > 0 {
|
||||
prefix := name[:idx]
|
||||
suffix := name[idx+1:]
|
||||
if len(suffix) > 0 && suffix[0] >= '0' && suffix[0] <= '9' &&
|
||||
len(prefix) > 0 && prefix[len(prefix)-1] >= '0' && prefix[len(prefix)-1] <= '9' {
|
||||
// Verify suffix is all digits (partition number, not part of device name)
|
||||
allDigits := true
|
||||
for _, c := range suffix {
|
||||
if c < '0' || c > '9' {
|
||||
allDigits = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if allDigits {
|
||||
return prefix // e.g., mmcblk0, nvme0n1
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// Standard: sda2 → sda, sdb1 → sdb
|
||||
|
||||
Reference in New Issue
Block a user