mirror of https://github.com/subgraph/fw-daemon
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
2.9 KiB
161 lines
2.9 KiB
// +build !go1.8
|
|
|
|
package main
|
|
|
|
import (
|
|
"sort"
|
|
"reflect"
|
|
|
|
"github.com/subgraph/fw-daemon/sgfw"
|
|
)
|
|
|
|
// Copied from golang 1.8 sources
|
|
// START sort.SliceStable
|
|
type lessSwap struct {
|
|
Less func(i, j int) bool
|
|
Swap func(i, j int)
|
|
}
|
|
|
|
func SliceStable(slice interface{}, less func(i, j int) bool) {
|
|
rv := reflect.ValueOf(slice)
|
|
swap := reflect.Swapper(slice)
|
|
stable_func(lessSwap{less, swap}, rv.Len())
|
|
}
|
|
|
|
func symMerge_func(data lessSwap, a, m, b int) {
|
|
if m-a == 1 {
|
|
i := m
|
|
j := b
|
|
for i < j {
|
|
h := int(uint(i+j) >> 1)
|
|
if data.Less(h, a) {
|
|
i = h + 1
|
|
} else {
|
|
j = h
|
|
}
|
|
}
|
|
for k := a; k < i-1; k++ {
|
|
data.Swap(k, k+1)
|
|
}
|
|
return
|
|
}
|
|
if b-m == 1 {
|
|
i := a
|
|
j := m
|
|
for i < j {
|
|
h := int(uint(i+j) >> 1)
|
|
if !data.Less(m, h) {
|
|
i = h + 1
|
|
} else {
|
|
j = h
|
|
}
|
|
}
|
|
for k := m; k > i; k-- {
|
|
data.Swap(k, k-1)
|
|
}
|
|
return
|
|
}
|
|
mid := int(uint(a+b) >> 1)
|
|
n := mid + m
|
|
var start, r int
|
|
if m > mid {
|
|
start = n - b
|
|
r = mid
|
|
} else {
|
|
start = a
|
|
r = m
|
|
}
|
|
p := n - 1
|
|
for start < r {
|
|
c := int(uint(start+r) >> 1)
|
|
if !data.Less(p-c, c) {
|
|
start = c + 1
|
|
} else {
|
|
r = c
|
|
}
|
|
}
|
|
end := n - start
|
|
if start < m && m < end {
|
|
rotate_func(data, start, m, end)
|
|
}
|
|
if a < start && start < mid {
|
|
symMerge_func(data, a, start, mid)
|
|
}
|
|
if mid < end && end < b {
|
|
symMerge_func(data, mid, end, b)
|
|
}
|
|
}
|
|
|
|
func swapRange_func(data lessSwap, a, b, n int) {
|
|
for i := 0; i < n; i++ {
|
|
data.Swap(a+i, b+i)
|
|
}
|
|
}
|
|
|
|
func rotate_func(data lessSwap, a, m, b int) {
|
|
i := m - a
|
|
j := b - m
|
|
for i != j {
|
|
if i > j {
|
|
swapRange_func(data, m-i, m, j)
|
|
i -= j
|
|
} else {
|
|
swapRange_func(data, m-i, m+j-i, i)
|
|
j -= i
|
|
}
|
|
}
|
|
swapRange_func(data, m-i, m, i)
|
|
}
|
|
|
|
func insertionSort_func(data lessSwap, a, b int) {
|
|
for i := a + 1; i < b; i++ {
|
|
for j := i; j > a && data.Less(j, j-1); j-- {
|
|
data.Swap(j, j-1)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Auto-generated variant of sort.go:stable
|
|
func stable_func(data lessSwap, n int) {
|
|
blockSize := 20
|
|
a, b := 0, blockSize
|
|
for b <= n {
|
|
insertionSort_func(data, a, b)
|
|
a = b
|
|
b += blockSize
|
|
}
|
|
insertionSort_func(data, a, n)
|
|
for blockSize < n {
|
|
a, b = 0, 2*blockSize
|
|
for b <= n {
|
|
symMerge_func(data, a, a+blockSize, b)
|
|
a = b
|
|
b += 2 * blockSize
|
|
}
|
|
if m := a + blockSize; m < n {
|
|
symMerge_func(data, a, m, n)
|
|
}
|
|
blockSize *= 2
|
|
}
|
|
}
|
|
// END sort.SliceStable
|
|
|
|
|
|
func (rl *ruleList) sortRules(rules []sgfw.DbusRule) []sgfw.DbusRule {
|
|
SliceStable(rules, func(i, j int) bool {
|
|
in := rules[i].Sandbox + rules[i].App + rules[i].Target
|
|
jn := rules[j].Sandbox + rules[j].App + rules[j].Target
|
|
order := []string{in,jn}
|
|
sort.Strings(order)
|
|
if rules[i].App == rules[j].App && rules[i].Sandbox == rules[j].Sandbox {
|
|
if sgfw.RuleAction(rules[i].Verb) == sgfw.RULE_ACTION_DENY || sgfw.RuleAction(rules[j].Verb) == sgfw.RULE_ACTION_DENY {
|
|
if rules[i].Verb != rules[j].Verb {
|
|
return (sgfw.RuleAction(rules[i].Verb) == sgfw.RULE_ACTION_DENY)
|
|
}
|
|
}
|
|
}
|
|
return (order[0] == in)
|
|
})
|
|
return rules
|
|
}
|