Fix nondeterminisim in xmlnotice
SafePathPrefixes contains "prebuilts/" which is a prefix of another
entry "prebuilts/module_sdk" which can both match the same path.
SafePathPrefixes is a map, so the iteration order is nondeterminisitic.
Move both SafePathPrefixes and SafePrebuiltPrefixes into lists that
will always have a deterministic iteration order.
Bug: 230357391
Test: build NOTICE.xml.gz multiple times
Change-Id: Ibfcd6715b70f26164e0ef4d59f73b240f47f8db7
diff --git a/tools/compliance/noticeindex.go b/tools/compliance/noticeindex.go
index 50f808b..86d42ac 100644
--- a/tools/compliance/noticeindex.go
+++ b/tools/compliance/noticeindex.go
@@ -360,19 +360,17 @@
continue
}
}
- for _, r := range OrderedSafePrebuiltPrefixes {
- prefix := SafePrebuiltPrefixes[r]
- match := r.FindString(licenseText)
+ for _, safePrebuiltPrefix := range safePrebuiltPrefixes {
+ match := safePrebuiltPrefix.re.FindString(licenseText)
if len(match) == 0 {
continue
}
- strip := SafePathPrefixes[prefix]
- if strip {
+ if safePrebuiltPrefix.strip {
// strip entire prefix
match = licenseText[len(match):]
} else {
// strip from prebuilts/ until safe prefix
- match = licenseText[len(match)-len(prefix):]
+ match = licenseText[len(match)-len(safePrebuiltPrefix.prefix):]
}
// remove LICENSE or NOTICE or other filename
li := strings.LastIndex(match, "/")
@@ -392,10 +390,10 @@
break
}
}
- for prefix, strip := range SafePathPrefixes {
- if strings.HasPrefix(p, prefix) {
- if strip {
- return p[len(prefix):]
+ for _, safePathPrefix := range safePathPrefixes {
+ if strings.HasPrefix(p, safePathPrefix.prefix) {
+ if safePathPrefix.strip {
+ return p[len(safePathPrefix.prefix):]
} else {
return p
}
diff --git a/tools/compliance/policy_policy.go b/tools/compliance/policy_policy.go
index 2787698..02d1d96 100644
--- a/tools/compliance/policy_policy.go
+++ b/tools/compliance/policy_policy.go
@@ -16,7 +16,6 @@
import (
"regexp"
- "sort"
"strings"
)
@@ -30,35 +29,31 @@
"toolchain": "toolchain",
}
- // SafePathPrefixes maps the path prefixes presumed not to contain any
+ // safePathPrefixes maps the path prefixes presumed not to contain any
// proprietary or confidential pathnames to whether to strip the prefix
// from the path when used as the library name for notices.
- SafePathPrefixes = map[string]bool{
- "external/": true,
- "art/": false,
- "build/": false,
- "cts/": false,
- "dalvik/": false,
- "developers/": false,
- "development/": false,
- "frameworks/": false,
- "packages/": true,
- "prebuilts/module_sdk/": true,
- "prebuilts/": false,
- "sdk/": false,
- "system/": false,
- "test/": false,
- "toolchain/": false,
- "tools/": false,
+ safePathPrefixes = []safePathPrefixesType{
+ {"external/", true},
+ {"art/", false},
+ {"build/", false},
+ {"cts/", false},
+ {"dalvik/", false},
+ {"developers/", false},
+ {"development/", false},
+ {"frameworks/", false},
+ {"packages/", true},
+ {"prebuilts/module_sdk/", true},
+ {"prebuilts/", false},
+ {"sdk/", false},
+ {"system/", false},
+ {"test/", false},
+ {"toolchain/", false},
+ {"tools/", false},
}
- // SafePrebuiltPrefixes maps the regular expression to match a prebuilt
+ // safePrebuiltPrefixes maps the regular expression to match a prebuilt
// containing the path of a safe prefix to the safe prefix.
- SafePrebuiltPrefixes = make(map[*regexp.Regexp]string)
-
- // OrderedSafePrebuiltPrefixes lists the SafePrebuiltPrefixes ordered by
- // increasing length.
- OrderedSafePrebuiltPrefixes = make([]*regexp.Regexp, 0, 0)
+ safePrebuiltPrefixes []safePrebuiltPrefixesType
// ImpliesUnencumbered lists the condition names representing an author attempt to disclaim copyright.
ImpliesUnencumbered = LicenseConditionSet(UnencumberedCondition)
@@ -89,6 +84,16 @@
ImpliesShared = LicenseConditionSet(ReciprocalCondition | RestrictedCondition | WeaklyRestrictedCondition)
)
+type safePathPrefixesType struct {
+ prefix string
+ strip bool
+}
+
+type safePrebuiltPrefixesType struct {
+ safePathPrefixesType
+ re *regexp.Regexp
+}
+
var (
anyLgpl = regexp.MustCompile(`^SPDX-license-identifier-LGPL.*`)
versionedGpl = regexp.MustCompile(`^SPDX-license-identifier-GPL-\p{N}.*`)
@@ -96,33 +101,15 @@
ccBySa = regexp.MustCompile(`^SPDX-license-identifier-CC-BY.*-SA.*`)
)
-// byIncreasingLength implements `sort.Interface` to order regular expressions by increasing length.
-type byIncreasingLength []*regexp.Regexp
-
-func (l byIncreasingLength) Len() int { return len(l) }
-func (l byIncreasingLength) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l byIncreasingLength) Less(i, j int) bool {
- ri := l[i].String()
- rj := l[j].String()
- if len(ri) == len(rj) {
- return ri < rj
- }
- return len(ri) < len(rj)
-}
-
func init() {
- for prefix := range SafePathPrefixes {
- if strings.HasPrefix(prefix, "prebuilts/") {
+ for _, safePathPrefix := range safePathPrefixes {
+ if strings.HasPrefix(safePathPrefix.prefix, "prebuilts/") {
continue
}
- r := regexp.MustCompile("^prebuilts/(?:runtime/mainline/)?" + prefix)
- SafePrebuiltPrefixes[r] = prefix
+ r := regexp.MustCompile("^prebuilts/(?:runtime/mainline/)?" + safePathPrefix.prefix)
+ safePrebuiltPrefixes = append(safePrebuiltPrefixes,
+ safePrebuiltPrefixesType{safePathPrefix, r})
}
- OrderedSafePrebuiltPrefixes = make([]*regexp.Regexp, 0, len(SafePrebuiltPrefixes))
- for r := range SafePrebuiltPrefixes {
- OrderedSafePrebuiltPrefixes = append(OrderedSafePrebuiltPrefixes, r)
- }
- sort.Sort(byIncreasingLength(OrderedSafePrebuiltPrefixes))
}
// LicenseConditionSetFromNames returns a set containing the recognized `names` and