Changeset 566 in code


Ignore:
Timestamp:
Jun 24, 2021, 5:33:46 PM (4 years ago)
Author:
hubert
Message:

Hand-made word splitter for BouncerServ

Remove the (direct) dependency on shlex (go-scfg still depends on it).

Co-authored-by: Simon Ser <contact@…>

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/go.mod

    r490 r566  
    77        git.sr.ht/~sircmpwn/go-bare v0.0.0-20210331145808-46f9b5e5bcf9
    88        github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
    9         github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
    109        github.com/klauspost/compress v1.11.13 // indirect
    1110        github.com/mattn/go-sqlite3 v1.14.6
  • trunk/service.go

    r546 r566  
    2222        "strings"
    2323        "time"
    24 
    25         "github.com/google/shlex"
     24        "unicode"
     25
    2626        "golang.org/x/crypto/bcrypt"
    2727        "gopkg.in/irc.v3"
     
    6464}
    6565
     66func splitWords(s string) ([]string, error) {
     67        var words []string
     68        var lastWord strings.Builder
     69        escape := false
     70        prev := ' '
     71        wordDelim := ' '
     72
     73        for _, r := range s {
     74                if escape {
     75                        // last char was a backslash, write the byte as-is.
     76                        lastWord.WriteRune(r)
     77                        escape = false
     78                } else if r == '\\' {
     79                        escape = true
     80                } else if wordDelim == ' ' && unicode.IsSpace(r) {
     81                        // end of last word
     82                        if !unicode.IsSpace(prev) {
     83                                words = append(words, lastWord.String())
     84                                lastWord.Reset()
     85                        }
     86                } else if r == wordDelim {
     87                        // wordDelim is either " or ', switch back to
     88                        // space-delimited words.
     89                        wordDelim = ' '
     90                } else if r == '"' || r == '\'' {
     91                        if wordDelim == ' ' {
     92                                // start of (double-)quoted word
     93                                wordDelim = r
     94                        } else {
     95                                // either wordDelim is " and r is ' or vice-versa
     96                                lastWord.WriteRune(r)
     97                        }
     98                } else {
     99                        lastWord.WriteRune(r)
     100                }
     101
     102                prev = r
     103        }
     104
     105        if !unicode.IsSpace(prev) {
     106                words = append(words, lastWord.String())
     107        }
     108
     109        if wordDelim != ' ' {
     110                return nil, fmt.Errorf("unterminated quoted string")
     111        }
     112        if escape {
     113                return nil, fmt.Errorf("unterminated backslash sequence")
     114        }
     115
     116        return words, nil
     117}
     118
    66119func handleServicePRIVMSG(dc *downstreamConn, text string) {
    67         words, err := shlex.Split(text)
    68         if err != nil {
    69                 sendServicePRIVMSG(dc, fmt.Sprintf("error: failed to parse command: %v", err))
     120        words, err := splitWords(text)
     121        if err != nil {
     122                sendServicePRIVMSG(dc, fmt.Sprintf(`error: failed to parse command: %v`, err))
    70123                return
    71124        }
Note: See TracChangeset for help on using the changeset viewer.