Browse Source

version: validate Long format on Android builds

Updates #14069

Change-Id: I134a90db561dacc4b1c1c66ccadac135b5d64cf3
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 1 year ago
parent
commit
d62baa45e6
3 changed files with 85 additions and 0 deletions
  1. 40 0
      version/version.go
  2. 17 0
      version/version_checkformat.go
  3. 28 0
      version/version_internal_test.go

+ 40 - 0
version/version.go

@@ -7,6 +7,7 @@ package version
 import (
 	"fmt"
 	"runtime/debug"
+	"strconv"
 	"strings"
 
 	tailscaleroot "tailscale.com"
@@ -169,3 +170,42 @@ func majorMinorPatch() string {
 	ret, _, _ := strings.Cut(Short(), "-")
 	return ret
 }
+
+func isValidLongWithTwoRepos(v string) bool {
+	s := strings.Split(v, "-")
+	if len(s) != 3 {
+		return false
+	}
+	hexChunk := func(s string) bool {
+		if len(s) < 6 {
+			return false
+		}
+		for i := range len(s) {
+			b := s[i]
+			if (b < '0' || b > '9') && (b < 'a' || b > 'f') {
+				return false
+			}
+		}
+		return true
+	}
+
+	v, t, g := s[0], s[1], s[2]
+	if !strings.HasPrefix(t, "t") || !strings.HasPrefix(g, "g") ||
+		!hexChunk(t[1:]) || !hexChunk(g[1:]) {
+		return false
+	}
+	nums := strings.Split(v, ".")
+	if len(nums) != 3 {
+		return false
+	}
+	for i, n := range nums {
+		bits := 8
+		if i == 2 {
+			bits = 16
+		}
+		if _, err := strconv.ParseUint(n, 10, bits); err != nil {
+			return false
+		}
+	}
+	return true
+}

+ 17 - 0
version/version_checkformat.go

@@ -0,0 +1,17 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build tailscale_go && android
+
+package version
+
+import "fmt"
+
+func init() {
+	// For official Android builds using the tailscale_go toolchain,
+	// panic if the builder is screwed up we fail to stamp a valid
+	// version string.
+	if !isValidLongWithTwoRepos(Long()) {
+		panic(fmt.Sprintf("malformed version.Long value %q", Long()))
+	}
+}

+ 28 - 0
version/version_internal_test.go

@@ -0,0 +1,28 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package version
+
+import "testing"
+
+func TestIsValidLongWithTwoRepos(t *testing.T) {
+	tests := []struct {
+		long string
+		want bool
+	}{
+		{"1.2.3-t01234abcde-g01234abcde", true},
+		{"1.2.259-t01234abcde-g01234abcde", true}, // big patch version
+		{"1.2.3-t01234abcde", false},              // missing repo
+		{"1.2.3-g01234abcde", false},              // missing repo
+		{"1.2.3-g01234abcde", false},              // missing repo
+		{"-t01234abcde-g01234abcde", false},
+		{"1.2.3", false},
+		{"1.2.3-t01234abcde-g", false},
+		{"1.2.3-t01234abcde-gERRBUILDINFO", false},
+	}
+	for _, tt := range tests {
+		if got := isValidLongWithTwoRepos(tt.long); got != tt.want {
+			t.Errorf("IsValidLongWithTwoRepos(%q) = %v; want %v", tt.long, got, tt.want)
+		}
+	}
+}