1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
package rfc5322
// 3.2.4. Quoted Strings
import "github.com/ProtonMail/gluon/rfcparser"
func parseQuotedString(p *rfcparser.Parser) (parserString, error) {
var result rfcparser.Bytes
result.Offset = p.CurrentToken().Offset
if _, err := tryParseCFWS(p); err != nil {
return parserString{}, err
}
if err := p.Consume(rfcparser.TokenTypeDQuote, "expected \" for quoted string start"); err != nil {
return parserString{}, err
}
for {
if ok, err := tryParseFWS(p); err != nil {
return parserString{}, err
} else if ok {
result.Value = append(result.Value, ' ')
}
if !(p.CheckWith(isQText) || p.Check(rfcparser.TokenTypeBackslash)) {
break
}
if p.CheckWith(isQText) {
b, err := parseQContent(p)
if err != nil {
return parserString{}, err
}
result.Value = append(result.Value, b)
} else {
b, err := parseQuotedPair(p)
if err != nil {
return parserString{}, err
}
result.Value = append(result.Value, b)
}
}
if ok, err := tryParseFWS(p); err != nil {
return parserString{}, err
} else if ok {
result.Value = append(result.Value, ' ')
}
if err := p.Consume(rfcparser.TokenTypeDQuote, "expected \" for quoted string end"); err != nil {
return parserString{}, err
}
if _, err := tryParseCFWS(p); err != nil {
return parserString{}, err
}
return parserString{
String: result.IntoString(),
Type: parserStringTypeOther,
}, nil
}
func parseQContent(p *rfcparser.Parser) (byte, error) {
if ok, err := p.MatchesWith(isQText); err != nil {
return 0, err
} else if ok {
return p.PreviousToken().Value, nil
}
return parseQuotedPair(p)
}
func isQText(tokenType rfcparser.TokenType) bool {
// qtext = %d33 / ; Printable US-ASCII
// %d35-91 / ; characters not including
// %d93-126 / ; "\" or the quote character
// obs-qtext
//
// obs-qtext = obs-NO-WS-CTL
//
if (rfcparser.IsCTL(tokenType) && !isObsNoWSCTL(tokenType)) ||
tokenType == rfcparser.TokenTypeDQuote ||
tokenType == rfcparser.TokenTypeBackslash ||
tokenType == rfcparser.TokenTypeSP ||
tokenType == rfcparser.TokenTypeEOF ||
tokenType == rfcparser.TokenTypeError {
return false
}
return true
}
|