summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-10-11 11:07:56 -0500
committerJeff Carr <[email protected]>2025-10-11 11:09:24 -0500
commit3eb1215f1105d98901bdb2a696f8ec14b7cf2efb (patch)
treed0dc399fc3101dc0408a8f9a6e65aeea1ade27b6
parent2677081b8e9514d689049af9f1450197df57ad08 (diff)
more removing of edge cases
-rw-r--r--doVerify.go47
-rw-r--r--version.go287
2 files changed, 334 insertions, 0 deletions
diff --git a/doVerify.go b/doVerify.go
index b936f24..09c8c74 100644
--- a/doVerify.go
+++ b/doVerify.go
@@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
+ "go.wit.com/lib/cobol"
"go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/zoopb"
"go.wit.com/log"
@@ -66,6 +67,35 @@ func doVerify() (string, error) {
counter += 1
continue
}
+ if p.Architecture == "" {
+ log.Printf("%-16.16s %-130.130s\n", "arch is blank", pdump)
+ counter += 1
+ continue
+ }
+ if p.Architecture != "amd64" {
+ log.Printf("%-16.16s %-130.130s\n", "arch is not x64", pdump)
+ continue
+ }
+ if p.DebInfo.Architecture != "" {
+ if p.Architecture != p.DebInfo.Architecture {
+ log.Printf("%-16.16s %-130.130s\n", "arch mismatch", p.Architecture, p.DebInfo.Architecture)
+ counter += 1
+ continue
+ }
+ }
+ if p.Version == "" {
+ log.Printf("%-16.16s %-130.130s\n", "version is blank", pdump)
+ counter += 1
+ continue
+ }
+ // verify constructed filename
+ constructedFilename := p.Package + "_" + p.Version + "_" + p.Architecture + ".deb"
+ _, fname := filepath.Split(p.Filename)
+ if constructedFilename != fname {
+ log.Info("filename mismatch", constructedFilename, fname, cobol.Since(p.Ctime))
+ return moveToBroken(p)
+ }
+
// log.Info("Package", p.Package)
if p.Ctime == nil {
log.Printf("ctime is nil %-130.130s\n", fullname)
@@ -87,3 +117,20 @@ func doVerify() (string, error) {
return "verified ok", nil
}
+
+func moveToBroken(p *zoopb.Package) (string, error) {
+ if err := os.Chdir(me.pb.BaseDir); err != nil {
+ return "no '" + me.pb.BaseDir + "' directory", err
+ }
+ brokendir := filepath.Join(me.pb.BaseDir, "broken")
+ if err := os.MkdirAll(brokendir, 0755); err != nil {
+ return "mkdir " + brokendir, err
+ }
+ _, fname := filepath.Split(p.Filename)
+ newname := filepath.Join(brokendir, fname)
+ if err := os.Rename(p.Filename, newname); err != nil {
+ return "rename failed " + newname, err
+ }
+ // panic("rename worked?")
+ return "rename worked " + newname, nil
+}
diff --git a/version.go b/version.go
new file mode 100644
index 0000000..a0bd0d4
--- /dev/null
+++ b/version.go
@@ -0,0 +1,287 @@
+package main
+
+// the origin repo was broken. pulled in from:
+// MIT License
+// Copyright (c) 2017 Teppei Fukuda
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "unicode"
+)
+
+type defaultNumSlice []int
+
+// get function returns 0, if the slice does not have the specified index.
+func (n defaultNumSlice) get(i int) int {
+ if len(n) > i {
+ return n[i]
+ }
+ return 0
+}
+
+type defaultStringSlice []string
+
+// get function returns "", if the slice does not have the specified index.
+func (s defaultStringSlice) get(i int) string {
+ if len(s) > i {
+ return s[i]
+ }
+ return ""
+}
+
+// Version represents a package version (http://man.he.net/man5/deb-version).
+type Version struct {
+ epoch int
+ upstreamVersion string
+ debianRevision string
+}
+
+var (
+ digitRegexp = regexp.MustCompile(`[0-9]+`)
+ nonDigitRegexp = regexp.MustCompile(`[^0-9]+`)
+)
+
+// NewDebVersion returns a parsed version
+func NewDebVersion(ver string) (version Version, err error) {
+ // Trim space
+ ver = strings.TrimSpace(ver)
+
+ // Parse epoch
+ splitted := strings.SplitN(ver, ":", 2)
+ if len(splitted) == 1 {
+ version.epoch = 0
+ ver = splitted[0]
+ } else {
+ version.epoch, err = strconv.Atoi(splitted[0])
+ if err != nil {
+ return Version{}, fmt.Errorf("epoch parse error: %v", err)
+ }
+
+ if version.epoch < 0 {
+ return Version{}, errors.New("epoch is negative")
+ }
+ ver = splitted[1]
+ }
+
+ // Parse upstream_version and debian_revision
+ index := strings.LastIndex(ver, "-")
+ if index >= 0 {
+ version.upstreamVersion = ver[:index]
+ version.debianRevision = ver[index+1:]
+
+ } else {
+ version.upstreamVersion = ver
+ }
+
+ // Verify upstream_version is valid
+ err = verifyUpstreamVersion(version.upstreamVersion)
+ if err != nil {
+ return Version{}, err
+ }
+
+ // Verify debian_revision is valid
+ err = verifyDebianRevision(version.debianRevision)
+ if err != nil {
+ return Version{}, err
+ }
+
+ return version, nil
+}
+
+func verifyUpstreamVersion(str string) error {
+ if len(str) == 0 {
+ return errors.New("upstream_version is empty")
+ }
+
+ // The upstream-version should start with a digit
+ if !unicode.IsDigit(rune(str[0])) {
+ return errors.New("upstream_version must start with digit")
+ }
+
+ // The upstream-version may contain only alphanumerics("A-Za-z0-9") and the characters .+-:~
+ allowedSymbols := ".-+~:_"
+ for _, s := range str {
+ if !unicode.IsDigit(s) && !unicode.IsLetter(s) && !strings.ContainsRune(allowedSymbols, s) {
+ return errors.New("upstream_version includes invalid character")
+ }
+ }
+ return nil
+}
+
+func verifyDebianRevision(str string) error {
+ // The debian-revision may contain only alphanumerics and the characters +.~
+ allowedSymbols := "+.~_"
+ for _, s := range str {
+ if !unicode.IsDigit(s) && !unicode.IsLetter(s) && !strings.ContainsRune(allowedSymbols, s) {
+ return errors.New("debian_revision includes invalid character")
+ }
+ }
+ return nil
+}
+
+// Valid validates the version
+func Valid(ver string) bool {
+ _, err := NewDebVersion(ver)
+ return err == nil
+}
+
+// Equal returns whether this version is equal with another version.
+func (v1 *Version) Equal(v2 Version) bool {
+ return v1.Compare(v2) == 0
+}
+
+// GreaterThan returns whether this version is greater than another version.
+func (v1 *Version) GreaterThan(v2 Version) bool {
+ return v1.Compare(v2) > 0
+}
+
+// LessThan returns whether this version is less than another version.
+func (v1 *Version) LessThan(v2 Version) bool {
+ return v1.Compare(v2) < 0
+}
+
+// Compare returns an integer comparing two version according to deb-version.
+// The result will be 0 if v1==v2, -1 if v1 < v2, and +1 if v1 > v2.
+func (v1 *Version) Compare(v2 Version) int {
+ // Equal
+ if reflect.DeepEqual(v1, v2) {
+ return 0
+ }
+
+ // Compare epochs
+ if v1.epoch > v2.epoch {
+ return 1
+ } else if v1.epoch < v2.epoch {
+ return -1
+ }
+
+ // Compare version
+ ret := compare(v1.upstreamVersion, v2.upstreamVersion)
+ if ret != 0 {
+ return ret
+ }
+
+ //Compare debian_revision
+ return compare(v1.debianRevision, v2.debianRevision)
+}
+
+// String returns the full version string
+func (v1 *Version) String() string {
+ version := ""
+ if v1.epoch > 0 {
+ version += fmt.Sprintf("%d:", v1.epoch)
+ }
+ version += v1.upstreamVersion
+
+ if v1.debianRevision != "" {
+ version += fmt.Sprintf("-%s", v1.debianRevision)
+
+ }
+ return version
+}
+
+func (v1 *Version) Epoch() int {
+ return v1.epoch
+}
+
+func (v1 *Version) Version() string {
+ return v1.upstreamVersion
+}
+
+func (v1 *Version) Revision() string {
+ return v1.debianRevision
+}
+
+func compare(v1, v2 string) int {
+ // Equal
+ if v1 == v2 {
+ return 0
+ }
+
+ // Extract digit strings and non-digit strings
+ numbers1, strings1 := extract(v1)
+ numbers2, strings2 := extract(v2)
+
+ if len(v1) > 0 && unicode.IsDigit(rune(v1[0])) {
+ strings1 = append([]string{""}, strings1...)
+ }
+ if len(v2) > 0 && unicode.IsDigit(rune(v2[0])) {
+ strings2 = append([]string{""}, strings2...)
+ }
+
+ index := max(len(numbers1), len(numbers2), len(strings1), len(strings2))
+ for i := 0; i < index; i++ {
+ // Compare non-digit strings
+ diff := compareString(strings1.get(i), strings2.get(i))
+ if diff != 0 {
+ return diff
+ }
+
+ // Compare digit strings
+ diff = numbers1.get(i) - numbers2.get(i)
+ if diff != 0 {
+ return diff
+ }
+ }
+
+ return 0
+}
+
+func compareString(s1, s2 string) int {
+ if s1 == s2 {
+ return 0
+ }
+
+ index := max(len(s1), len(s2))
+ for i := 0; i < index; i++ {
+ a := 0
+ if i < len(s1) {
+ a = order(rune(s1[i]))
+ }
+
+ b := 0
+ if i < len(s2) {
+ b = order(rune(s2[i]))
+ }
+
+ if a != b {
+ return a - b
+ }
+ }
+ return 0
+}
+
+// order function returns the number corresponding to rune
+func order(r rune) int {
+ // all the letters sort earlier than all the non-letters
+ if unicode.IsLetter(r) {
+ return int(r)
+ }
+
+ // a tilde sorts before anything
+ if r == '~' {
+ return -1
+ }
+
+ return int(r) + 256
+}
+
+func extract(version string) (defaultNumSlice, defaultStringSlice) {
+ numbers := digitRegexp.FindAllString(version, -1)
+
+ var dnum defaultNumSlice
+ for _, number := range numbers {
+ n, _ := strconv.Atoi(number)
+ dnum = append(dnum, n)
+ }
+
+ s := nonDigitRegexp.FindAllString(version, -1)
+
+ return dnum, defaultStringSlice(s)
+
+}