|
|
|
@ -2,7 +2,7 @@ package main |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"bufio" |
|
|
|
"bufio" |
|
|
|
"crypto/sha1" |
|
|
|
"crypto/sha256" |
|
|
|
"encoding/binary" |
|
|
|
"encoding/binary" |
|
|
|
"encoding/hex" |
|
|
|
"encoding/hex" |
|
|
|
"encoding/json" |
|
|
|
"encoding/json" |
|
|
|
@ -10,6 +10,7 @@ import ( |
|
|
|
"flag" |
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"log" |
|
|
|
"log" |
|
|
|
|
|
|
|
"math" |
|
|
|
"net/url" |
|
|
|
"net/url" |
|
|
|
"os" |
|
|
|
"os" |
|
|
|
"os/user" |
|
|
|
"os/user" |
|
|
|
@ -19,6 +20,7 @@ import ( |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
"unicode" |
|
|
|
"unicode" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/coreos/go-semver/semver" |
|
|
|
"github.com/curusarn/resh/pkg/records" |
|
|
|
"github.com/curusarn/resh/pkg/records" |
|
|
|
giturls "github.com/whilp/git-urls" |
|
|
|
giturls "github.com/whilp/git-urls" |
|
|
|
) |
|
|
|
) |
|
|
|
@ -178,7 +180,7 @@ func (s *sanitizer) sanitizeRecord(record *records.Record) error { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if len(record.RecallActionsRaw) > 0 { |
|
|
|
if len(record.RecallActionsRaw) > 0 { |
|
|
|
record.RecallActionsRaw, err = s.sanitizeRecallActions(record.RecallActionsRaw) |
|
|
|
record.RecallActionsRaw, err = s.sanitizeRecallActions(record.RecallActionsRaw, record.ReshVersion) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
log.Fatal("RecallActionsRaw:", record.RecallActionsRaw, "; sanitization error:", err) |
|
|
|
log.Fatal("RecallActionsRaw:", record.RecallActionsRaw, "; sanitization error:", err) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -188,44 +190,80 @@ func (s *sanitizer) sanitizeRecord(record *records.Record) error { |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// sanitizes the recall actions by replacing the recall prefix with it's length
|
|
|
|
func fixSeparator(str string) string { |
|
|
|
func (s *sanitizer) sanitizeRecallActions(str string) (string, error) { |
|
|
|
if len(str) > 0 && str[0] == ';' { |
|
|
|
sanStr := "" |
|
|
|
return "|||" + str[1:] |
|
|
|
divider := ";" |
|
|
|
} |
|
|
|
if strings.Contains(str, "|||") { |
|
|
|
return str |
|
|
|
divider = "|||" |
|
|
|
} |
|
|
|
// normal mode
|
|
|
|
|
|
|
|
} |
|
|
|
func minIndex(str string, substrs []string) (idx, substrIdx int) { |
|
|
|
for x, actionStr := range strings.Split(str, divider+"arrow_") { |
|
|
|
minMatch := math.MaxInt32 |
|
|
|
if x == 0 { |
|
|
|
for i, sep := range substrs { |
|
|
|
continue |
|
|
|
match := strings.Index(str, sep) |
|
|
|
|
|
|
|
if match != -1 && match < minMatch { |
|
|
|
|
|
|
|
minMatch = match |
|
|
|
|
|
|
|
substrIdx = i |
|
|
|
} |
|
|
|
} |
|
|
|
if len(actionStr) == 0 { |
|
|
|
} |
|
|
|
return str, errors.New("Action can't be empty; idx=" + strconv.Itoa(x)) |
|
|
|
idx = minMatch |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sanitizes the recall actions by replacing the recall prefix with it's length
|
|
|
|
|
|
|
|
func (s *sanitizer) sanitizeRecallActions(str string, reshVersion string) (string, error) { |
|
|
|
|
|
|
|
if len(str) == 0 { |
|
|
|
|
|
|
|
return "", nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var separators []string |
|
|
|
|
|
|
|
seps := []string{"|||"} |
|
|
|
|
|
|
|
refVersion, err := semver.NewVersion("2.5.14") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return str, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(reshVersion) == 0 { |
|
|
|
|
|
|
|
return str, errors.New("sanitizeRecallActions: record.ReshVersion is an empty string") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
recordVersion, err := semver.NewVersion(reshVersion[1:]) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return str, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if recordVersion.LessThan(*refVersion) { |
|
|
|
|
|
|
|
seps = append(seps, ";") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
actions := []string{"arrow_up", "arrow_down", "control_R"} |
|
|
|
|
|
|
|
for _, sep := range seps { |
|
|
|
|
|
|
|
for _, action := range actions { |
|
|
|
|
|
|
|
separators = append(separators, sep+action+":") |
|
|
|
} |
|
|
|
} |
|
|
|
var action string |
|
|
|
} |
|
|
|
var prefix string |
|
|
|
/* |
|
|
|
if strings.HasPrefix(actionStr, "up:") { |
|
|
|
- find any of {|||,;}{arrow_up,arrow_down,control_R}: in the recallActions (on the lowest index) |
|
|
|
action = "arrow_up" |
|
|
|
- use found substring to parse out the next prefix |
|
|
|
if len(actionStr) < 3 { |
|
|
|
- sanitize prefix |
|
|
|
return str, errors.New("Action is too short:" + actionStr) |
|
|
|
- add fixed substring and sanitized prefix to output |
|
|
|
} |
|
|
|
*/ |
|
|
|
if len(actionStr) != 3 { |
|
|
|
doBreak := false |
|
|
|
prefix = actionStr[4:] |
|
|
|
sanStr := "" |
|
|
|
} |
|
|
|
idx := 0 |
|
|
|
} else if strings.HasPrefix(actionStr, "down:") { |
|
|
|
var currSeparator string |
|
|
|
action = "arrow_down" |
|
|
|
tokenLen, sepIdx := minIndex(str, separators) |
|
|
|
if len(actionStr) < 5 { |
|
|
|
if tokenLen != 0 { |
|
|
|
return str, errors.New("Action is too short:" + actionStr) |
|
|
|
return str, errors.New("sanitizeReacallActions: unexpected string before first action/separator") |
|
|
|
} |
|
|
|
} |
|
|
|
if len(actionStr) != 5 { |
|
|
|
currSeparator = separators[sepIdx] |
|
|
|
prefix = actionStr[6:] |
|
|
|
idx += len(currSeparator) |
|
|
|
} |
|
|
|
for !doBreak { |
|
|
|
} else { |
|
|
|
tokenLen, sepIdx := minIndex(str[idx:], separators) |
|
|
|
return str, errors.New("Action should start with one of (arrow_up, arrow_down); got: arrow_" + actionStr) |
|
|
|
if tokenLen > len(str[idx:]) { |
|
|
|
|
|
|
|
tokenLen = len(str[idx:]) |
|
|
|
|
|
|
|
doBreak = true |
|
|
|
} |
|
|
|
} |
|
|
|
sanPrefix := strconv.Itoa(len(prefix)) |
|
|
|
// token := str[idx : idx+tokenLen]
|
|
|
|
sanStr += "|||" + action + ":" + sanPrefix |
|
|
|
sanStr += fixSeparator(currSeparator) + strconv.Itoa(tokenLen) |
|
|
|
|
|
|
|
idx += tokenLen + len(currSeparator) |
|
|
|
|
|
|
|
currSeparator = separators[sepIdx] |
|
|
|
} |
|
|
|
} |
|
|
|
return sanStr, nil |
|
|
|
return sanStr, nil |
|
|
|
} |
|
|
|
} |
|
|
|
@ -442,21 +480,17 @@ func (s *sanitizer) hashToken(token string) string { |
|
|
|
if len(token) <= 0 { |
|
|
|
if len(token) <= 0 { |
|
|
|
return token |
|
|
|
return token |
|
|
|
} |
|
|
|
} |
|
|
|
// hash with sha1
|
|
|
|
// hash with sha256
|
|
|
|
h := sha1.New() |
|
|
|
sum := sha256.Sum256([]byte(token)) |
|
|
|
h.Write([]byte(token)) |
|
|
|
return s.trimHash(hex.EncodeToString(sum[:])) |
|
|
|
sum := h.Sum(nil) |
|
|
|
|
|
|
|
return s.trimHash(hex.EncodeToString(sum)) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (s *sanitizer) hashNumericToken(token string) string { |
|
|
|
func (s *sanitizer) hashNumericToken(token string) string { |
|
|
|
if len(token) <= 0 { |
|
|
|
if len(token) <= 0 { |
|
|
|
return token |
|
|
|
return token |
|
|
|
} |
|
|
|
} |
|
|
|
h := sha1.New() |
|
|
|
sum := sha256.Sum256([]byte(token)) |
|
|
|
h.Write([]byte(token)) |
|
|
|
sumInt := int(binary.LittleEndian.Uint64(sum[:])) |
|
|
|
sum := h.Sum(nil) |
|
|
|
|
|
|
|
sumInt := int(binary.LittleEndian.Uint64(sum)) |
|
|
|
|
|
|
|
if sumInt < 0 { |
|
|
|
if sumInt < 0 { |
|
|
|
return strconv.Itoa(sumInt * -1) |
|
|
|
return strconv.Itoa(sumInt * -1) |
|
|
|
} |
|
|
|
} |
|
|
|
|