github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/base64_finder.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import ( 7 "encoding/base64" 8 "regexp" 9 "strings" 10 ) 11 12 type Base64Finder struct { 13 input string 14 lines []string 15 base64blocks []string 16 } 17 18 var b64FindRE = regexp.MustCompile(`^\s*(([a-zA-Z0-9/+_-]+)(={0,3}))\s*$`) 19 20 func NewBase64Finder(i string) *Base64Finder { 21 return &Base64Finder{input: i} 22 } 23 24 func (s *Base64Finder) split() { 25 s.lines = strings.Split(s.input, "\n") 26 } 27 28 func (s *Base64Finder) findAll() { 29 i := 0 30 for i >= 0 { 31 var msg string 32 msg, i = s.findOne(i) 33 if len(msg) > 0 { 34 s.base64blocks = append(s.base64blocks, msg) 35 } 36 } 37 } 38 39 func (s *Base64Finder) search(searchFor []byte, url bool) bool { 40 41 var encoding *base64.Encoding 42 43 if url { 44 encoding = base64.URLEncoding 45 } else { 46 encoding = base64.StdEncoding 47 } 48 49 i := 0 50 for i >= 0 { 51 var msg string 52 msg, i = s.findOne(i) 53 if len(msg) > 0 { 54 buf, err := encoding.DecodeString(msg) 55 if err == nil && FastByteArrayEq(searchFor, buf) { 56 return true 57 } 58 } 59 } 60 61 return false 62 } 63 64 func (s *Base64Finder) findOne(i int) (string, int) { 65 var parts []string 66 l := len(s.lines) 67 state := 0 68 69 for ; i < l; i++ { 70 line := s.lines[i] 71 match := b64FindRE.FindStringSubmatch(line) 72 if match != nil { 73 state = 1 74 parts = append(parts, match[1]) 75 if len(match[3]) > 0 { 76 // A terminal "=" character means jump on out 77 i++ 78 break 79 } 80 } else if state == 1 { 81 break 82 } 83 84 // wait until next time 85 } 86 if i == l { 87 i = -1 88 } 89 ret := strings.Join(parts, "") 90 return ret, i 91 } 92 93 func (s *Base64Finder) Run() []string { 94 s.split() 95 s.findAll() 96 return s.base64blocks 97 } 98 99 func FindBase64Blocks(s string) []string { 100 eng := NewBase64Finder(s) 101 return eng.Run() 102 } 103 104 func FindFirstBase64Block(s string) string { 105 v := FindBase64Blocks(s) 106 if len(v) > 0 { 107 return v[0] 108 } 109 return "" 110 } 111 112 var snipRE = regexp.MustCompile(`(([a-zA-Z0-9/+_-]+)(={0,3}))`) 113 114 func FindBase64Snippets(s string) []string { 115 return snipRE.FindAllString(s, -1) 116 } 117 118 func FindBase64Block(s string, pattern []byte, url bool) bool { 119 eng := NewBase64Finder(s) 120 eng.split() 121 return eng.search(pattern, url) 122 }