private IList<string> ParseGroupLists(
   string str,
   int index,
   int endIndex) {
        var groups = new List<string>();
        var tokener = new Tokener();
        this.Parse(str, index, endIndex, tokener);
        foreach (int[] token in tokener.GetTokens()) {
          if (token[0] == HeaderParserUtility.TokenGroup) {
            int startIndex = token[1];
            endIndex = token[2];
            string groupList = HeaderParserUtility.ParseGroupList(
str,
startIndex,
endIndex);
            groupList = ParserUtility.TrimSpaceAndTab(groupList);
            groups.Add(groupList);
          }
        }
        return groups;
      }
Beispiel #2
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Mail.NamedAddress.#ctor(System.String)"]/*'/>
 public NamedAddress(string address)
 {
     if (address == null) {
     throw new ArgumentNullException("address");
       }
       var tokener = new Tokener();
       if (HeaderParser.ParseAddress(address, 0, address.Length, tokener) !=
     address.Length) {
     throw new ArgumentException("Address has an invalid syntax.");
       }
       NamedAddress na = HeaderParserUtility.ParseAddress(
       address,
       0,
       address.Length,
       tokener.GetTokens());
       if (na == null) {
     throw new ArgumentException("Address has an invalid syntax.");
       }
       this.displayName = na.displayName;
       this.address = na.address;
       this.groupAddresses = na.groupAddresses;
       this.isGroup = na.isGroup;
 }
Beispiel #3
0
 internal static IList<NamedAddress> ParseAddresses(string value) {
   var tokener = new Tokener();
   if (value == null) {
     return new List<NamedAddress>();
   }
   // Check for valid syntax
   return (HeaderParser.ParseHeaderTo(value, 0, value.Length, tokener) !=
           value.Length) ? (new List<NamedAddress>()) :
     HeaderParserUtility.ParseAddressList(
       value,
       0,
       value.Length,
       tokener.GetTokens());
 }
            public string DecodeEncodedWords(string str)
            {
                #if DEBUG
                if (str == null) {
                  throw new ArgumentNullException("str");
                }
                #endif

                // For structured header fields that allow comments only wherever
                // whitespace
                // is allowed, and allow parentheses only for comments
                if (str.Length < 9) {
                  // too short for encoded words
                  return str;
                }
                if (str.IndexOf("=?", StringComparison.Ordinal) < 0) {
                  // No encoded words
                  return str;
                }
                var sb = new StringBuilder();
                var tokener = new Tokener();
                int endIndex = this.Parse(str, 0, str.Length, tokener);
                if (endIndex != str.Length) {
                  // The header field is syntactically invalid,
                  // so don't decode any encoded words
                  // Console.WriteLine("Invalid syntax: " + this.GetType().Name +
                  // ", " + str);
                  return str;
                }
                var lastIndex = 0;
                // Get each relevant token sorted by starting index
                IList<int[]> tokens = tokener.GetTokens();
                foreach (int[] token in tokens) {
                  // Console.WriteLine("" + token[0] + " [" +
                  // (str.Substring(token[1],token[2]-token[1])) + "]");
                  if (token[0] == HeaderParserUtility.TokenComment && token[0] >=
                   lastIndex) {
                // This is a comment token
                int startIndex = token[1];
                endIndex = token[2];
                string newComment = Rfc2047.DecodeEncodedWords(
                  str,
                  startIndex + 1,
                  endIndex - 1,
                  EncodedWordContext.Comment);
                sb.Append(str.Substring(lastIndex, startIndex + 1 - lastIndex));
                sb.Append(newComment);
                lastIndex = endIndex - 1;
                  } else if (token[0] == HeaderParserUtility.TokenPhrase) {
                // This is a phrase token
                int startIndex = token[1];
                endIndex = token[2];
                string newComment = Rfc2047.DecodePhraseText(
                  str,
                  startIndex,
                  endIndex,
                  tokens,
                  true);
                sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                sb.Append(newComment);
                lastIndex = endIndex;
                  }
                }
                sb.Append(str.Substring(lastIndex, str.Length - lastIndex));
                return sb.ToString();
            }
Beispiel #5
0
 public void Greater()
 {
     Assert.AreEqual(Token.Greater(), Tokener.Tokenize(">").First());
 }
Beispiel #6
0
 public void IdentifierLowerCaseOnly()
 {
     Assert.AreEqual(Token.Ident("foo"), Tokener.Tokenize("foo").First());
 }
Beispiel #7
0
 public void Equals()
 {
     Assert.AreEqual(Token.Equals(), Tokener.Tokenize("=").First());
 }
Beispiel #8
0
 public void RightBracket()
 {
     Assert.AreEqual(Token.RightBracket(), Tokener.Tokenize("]").First());
 }
Beispiel #9
0
 public void InvalidChar()
 {
     Tokener.Tokenize("what?").ToArray();
 }
Beispiel #10
0
 public void EmptyInput()
 {
     Assert.AreEqual(Token.Eoi(), Tokener.Tokenize(string.Empty).Single());
 }
Beispiel #11
0
 public void WhiteSpace()
 {
     Assert.AreEqual(Token.WhiteSpace(" \r \n \f \t "), Tokener.Tokenize(" \r \n \f \t etc").First());
 }
Beispiel #12
0
 public void SubstringMatch()
 {
     Assert.AreEqual(TokenKind.SubstringMatch, Tokener.Tokenize("*=").First().Kind);
 }
Beispiel #13
0
 public void Integer()
 {
     Assert.AreEqual(Token.Integer("42"), Tokener.Tokenize("42").First());
 }
Beispiel #14
0
 public void Function()
 {
     Assert.AreEqual(Token.Function("funky"), Tokener.Tokenize("funky(").First());
 }
Beispiel #15
0
 public void BadHash()
 {
     Tokener.Tokenize("#").ToArray();
 }
Beispiel #16
0
 public string UncommentAndCollapse(string str)
 {
     var sb = new StringBuilder();
     var tokener = new Tokener();
     int endIndex = this.Parse(str, 0, str.Length, tokener);
     if (endIndex != str.Length) {
       // The header field is syntactically invalid
       return str;
     }
     var lastIndex = 0;
     // Get each relevant token sorted by starting index
     IList<int[]> tokens = tokener.GetTokens();
     foreach (int[] token in tokens) {
       if (token[0] == HeaderParserUtility.TokenComment && token[0] >=
        lastIndex) {
     // This is a comment token; ignore the comment
     int startIndex = token[1];
     endIndex = token[2];
     sb.Append(str.Substring(lastIndex, startIndex + 1 - lastIndex));
     lastIndex = endIndex - 1;
       }
     }
     sb.Append(str.Substring(lastIndex, str.Length - lastIndex));
     string ret = sb.ToString();
     ret = ParserUtility.TrimAndCollapseSpaceAndTab(ret);
     return ret;
 }
Beispiel #17
0
 public void CommaWhiteSpacePrepended()
 {
     Assert.AreEqual(Token.Comma(), Tokener.Tokenize("  ,").First());
 }
Beispiel #18
0
 public void Star()
 {
     Assert.AreEqual(Token.Char('*'), Tokener.Tokenize("*").First());
 }
Beispiel #19
0
 public void StringSingleQuotedWithEscapedBackslashes()
 {
     Assert.AreEqual(Token.String(@"foo \bar\ baz"), Tokener.Tokenize(@"'foo \\bar\\ baz'").First());
 }
Beispiel #20
0
 public void Comma()
 {
     Assert.AreEqual(Token.Comma(), Tokener.Tokenize(",").First());
 }
Beispiel #21
0
 public void StarStar()
 {
     Assert.AreEqual(new[] { Token.Char('*'), Token.Char('*') }, Tokener.Tokenize("**").Take(2).ToArray());
 }
Beispiel #22
0
 public void Plus()
 {
     Assert.AreEqual(Token.Plus(), Tokener.Tokenize("+").First());
 }
Beispiel #23
0
 public void Tilde()
 {
     Assert.AreEqual(TokenKind.Tilde, Tokener.Tokenize("~").First().Kind);
 }
Beispiel #24
0
 public void LeftBracket()
 {
     Assert.AreEqual(Token.LeftBracket(), Tokener.Tokenize("[").First());
 }
Beispiel #25
0
 public void TildeWhitespacePrepended()
 {
     Assert.AreEqual(TokenKind.Tilde, Tokener.Tokenize("  ~").First().Kind);
 }
Beispiel #26
0
 public void PlusWhiteSpacePrepended()
 {
     Assert.AreEqual(Token.Plus(), Tokener.Tokenize("  +").First());
 }
Beispiel #27
0
 public void StringSingleQuoteUnterminated()
 {
     Tokener.Tokenize("'foo").ToArray();
 }
Beispiel #28
0
 public void GreaterWhiteSpacePrepended()
 {
     Assert.AreEqual(Token.Greater(), Tokener.Tokenize("  >").First());
 }
Beispiel #29
0
 public void StringDoubleQuoteUnterminated()
 {
     Tokener.Tokenize("\"foo").ToArray();
 }
Beispiel #30
0
 public void Invalid(string selector)
 {
     Assert.Throws <FormatException>(() =>
                                     Parser.Parse(Tokener.Tokenize(selector), new NoSelectorGenerator()));
 }
Beispiel #31
0
 public void StringInvalidEscaping()
 {
     Tokener.Tokenize(@"'f\oo").ToArray();
 }
Beispiel #32
0
 internal static IList<NamedAddress> ParseAddresses(string[] values) {
   var tokener = new Tokener();
   var list = new List<NamedAddress>();
   foreach (string addressValue in values) {
     if (addressValue == null) {
       continue;
     }
     if (
       HeaderParser.ParseHeaderTo(
         addressValue,
         0,
         addressValue.Length,
         tokener) != addressValue.Length) {
       // Invalid syntax
       continue;
     }
     list.AddRange(
       HeaderParserUtility.ParseAddressList(
         addressValue,
         0,
         addressValue.Length,
         tokener.GetTokens()));
   }
   return list;
 }
Beispiel #33
0
 public void NullReader()
 {
     Tokener.Tokenize((TextReader)null);
 }
Beispiel #34
0
            public string DowngradeFieldValue(string str)
            {
                string originalString = str;
                IList<string> originalGroups = null;
                for (int phase = 0; phase < 5; ++phase) {
                  if (str.IndexOf('(') < 0 && phase == 0) {
                // No comments in the header field value, a common case
                continue;
                  }
                  if (!Message.HasTextToEscape(str)) {
                // No text needs to be encoded
                return str;
                  }
                  var sb = new StringBuilder();
                  var tokener = new Tokener();
                  int endIndex = this.Parse(str, 0, str.Length, tokener);
                  if (endIndex != str.Length) {
                // The header field is syntactically invalid,
                // so downgrading is not possible
                return str;
                  }
                  var lastIndex = 0;
                  // Get each relevant token sorted by starting index
                  IList<int[]> tokens = tokener.GetTokens();
                  var groupIndex = 0;
                  // TODO: Received field downgrading
                  foreach (int[] token in tokens) {
                if (token[1] < lastIndex) {
                  continue;
                }
                // NOTE: Doesn't downgrade ID-Left or ID-Right
                // if extended characters appear in those areas
                switch (phase) {
                  case 0: {
                  // Comment downgrading
                  if (token[0] == HeaderParserUtility.TokenComment) {
                    int startIndex = token[1];
                    endIndex = token[2];
                    // Console.WriteLine(str.Substring(startIndex, endIndex -
                    // startIndex));
                    if (Message.HasTextToEscape(str, startIndex, endIndex)) {
                    string newComment = Rfc2047.EncodeComment(
                  str,
                  startIndex,
                  endIndex);
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    sb.Append(newComment);
                    } else {
                    // No text needs to be escaped, output the comment as is
                    sb.Append(str.Substring(lastIndex, endIndex - lastIndex));
                    }
                    lastIndex = endIndex;
                  }

                  break;
                }
                  case 1: {
                  // Phrase downgrading
                  if (token[0] == HeaderParserUtility.TokenPhrase) {
                    int startIndex = token[1];
                    endIndex = token[2];
                    string newComment = Rfc2047.EncodePhraseText(
                str,
                startIndex,
                endIndex,
                tokens);
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    sb.Append(newComment);
                    lastIndex = endIndex;
                  }

                  break;
                }
                  case 2: {
                  // Group downgrading
                  if (token[0] == HeaderParserUtility.TokenGroup) {
                    int startIndex = token[1];
                    endIndex = token[2];
                    var nonasciiLocalParts = false;
                    var displayNameEnd = -1;
                    string originalGroupList;
                    foreach (int[] token2 in tokens) {
                    if (token2[0] == HeaderParserUtility.TokenPhrase) {
                    if (displayNameEnd < 0) {
                    displayNameEnd = token2[2];
                    }
                    }
                    if (token2[0] == HeaderParserUtility.TokenLocalPart) {
                    if (token2[1] >= startIndex && token2[2] <= endIndex) {
                    // Local part within a group
                    if (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    str,
                    token2[1],
                    token2[2])) {
                    nonasciiLocalParts = true;
                    break;
                    }
                    }
                    }
                    }
                    if (!nonasciiLocalParts) {
                    int localLastIndex = startIndex;
                    var nonasciiDomains = false;
                    var sb2 = new StringBuilder();
                    foreach (int[] token2 in tokens) {
                    if (token2[0] == HeaderParserUtility.TokenDomain) {
                    if (token2[1] >= startIndex && token2[2] <= endIndex) {
                    // Domain within the group
                    string domain = HeaderParserUtility.ParseDomain(
                    str,
                    token2[1],
                    token[2]);
                    // NOTE: "domain" can include domain literals, enclosed
                    // in brackets; they are invalid under
                    // "IsValidDomainName" .
                    domain = (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    domain,
                    0,
                    domain.Length) && Idna.IsValidDomainName(
                    domain,
                    false)) ? Idna.EncodeDomainName(
                    domain) : str.Substring(
                    token2[1],
                    token2[2] - token2[1]);
                    if (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    domain,
                    0,
                    domain.Length)) {
                    // ASCII encoding failed
                    nonasciiDomains = true;
                    break;
                    }
                    sb2.Append(
                    str.Substring(
                    localLastIndex,
                    token2[1] - localLastIndex));
                    sb2.Append(domain);
                    localLastIndex = token2[2];
                    }
                    }
                    }
                    nonasciiLocalParts = nonasciiDomains;
                    if (!nonasciiLocalParts) {
                    // All of the domains could be converted to ASCII
                    sb2.Append(
                  str.Substring(
                  localLastIndex,
                  endIndex - localLastIndex));
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    sb.Append(sb2.ToString());
                    lastIndex = endIndex;
                    }
                    }
                    if (nonasciiLocalParts) {
                    // At least some of the domains could not
                    // be converted to ASCII
                    originalGroups = originalGroups ?? this.ParseGroupLists(
                  originalString,
                  0,
                  originalString.Length);
                    originalGroupList = originalGroups[groupIndex];
                    string groupText = originalGroupList;
                    string displayNameText = str.Substring(
                  startIndex,
                  displayNameEnd - startIndex);
                    string encodedText = displayNameText + " " +
                    Rfc2047.EncodeString(groupText) + " :;";
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    sb.Append(encodedText);
                    lastIndex = endIndex;
                    }
                    ++groupIndex;
                  }

                  break;
                }
                  case 3: {
                 // Mailbox downgrading
                  if (token[0] == HeaderParserUtility.TokenMailbox) {
                    int startIndex = token[1];
                    endIndex = token[2];
                    var nonasciiLocalPart = false;
                    var hasPhrase = false;
                    foreach (int[] token2 in tokens) {
                    hasPhrase |= token2[0] == HeaderParserUtility.TokenPhrase;
                    if (token2[0] == HeaderParserUtility.TokenLocalPart) {
                    if (token2[1] >= startIndex && token2[2] <= endIndex) {
                    if (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    str,
                    token2[1],
                    token2[2])) {
                    nonasciiLocalPart = true;
                    break;
                    }
                    }
                    }
                    }
                    if (!nonasciiLocalPart) {
                    int localLastIndex = startIndex;
                    var nonasciiDomains = false;
                    var sb2 = new StringBuilder();
                    foreach (int[] token2 in tokens) {
                    if (token2[0] == HeaderParserUtility.TokenDomain) {
                    if (token2[1] >= startIndex && token2[2] <= endIndex) {
                    // Domain within the group
                    string domain = HeaderParserUtility.ParseDomain(
                    str,
                    token2[1],
                    token[2]);
                    // NOTE: "domain" can include domain literals, enclosed
                    // in brackets; they are invalid under
                    // "IsValidDomainName" .
                    domain = (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    domain,
                    0,
                    domain.Length) && Idna.IsValidDomainName(
                    domain,
                    false)) ? Idna.EncodeDomainName(
                    domain) : str.Substring(
                    token2[1],
                    token2[2] - token2[1]);
                    if (
                    Message.HasTextToEscapeIgnoreEncodedWords(
                    domain,
                    0,
                    domain.Length)) {
                    // ASCII encoding failed
                    nonasciiDomains = true;
                    break;
                    }
                    sb2.Append(
                    str.Substring(
                    localLastIndex,
                    token2[1] - localLastIndex));
                    sb2.Append(domain);
                    localLastIndex = token2[2];
                    }
                    }
                    }
                    nonasciiLocalPart = nonasciiDomains;
                    if (!nonasciiLocalPart) {
                    // All of the domains could be converted to ASCII
                    sb2.Append(
                  str.Substring(
                  localLastIndex,
                  endIndex - localLastIndex));
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    sb.Append(sb2.ToString());
                    lastIndex = endIndex;
                    }
                    }
                    // Downgrading failed
                    if (nonasciiLocalPart) {
                    sb.Append(str.Substring(lastIndex, startIndex - lastIndex));
                    if (!hasPhrase) {
                    string addrSpec = str.Substring(
                token[1],
                token[2] - token[1]);
                    string encodedText = " " + Rfc2047.EncodeString(addrSpec) +
                    " :;";
                    sb.Append(encodedText);
                    } else {
                    // Has a phrase, extract the addr-spec and convert
                    // the mailbox to a group
                    int angleAddrStart = HeaderParser.ParsePhrase(
                    str,
                    token[1],
                    token[2],
                    null);
                    // append the rest of the string so far up to and
                    // including the phrase
                    sb.Append(
                 str.Substring(
                 lastIndex,
                 angleAddrStart - lastIndex));
                    int addrSpecStart = HeaderParser.ParseCFWS(
                str,
                angleAddrStart,
                token[2],
                null);
                    if (addrSpecStart < token[2] && str[addrSpecStart] == '<') {
                    ++addrSpecStart;
                    }
                    addrSpecStart = HeaderParser.ParseObsRoute(
                    str,
                    addrSpecStart,
                    token[2],
                    null);
                    int addrSpecEnd = HeaderParser.ParseAddrSpec(
                str,
                addrSpecStart,
                token[2],
                null);
                    string addrSpec = str.Substring(
                    addrSpecStart,
                    addrSpecEnd - addrSpecStart);
                    string valueSbString = sb.ToString();
                bool endsWithSpace = sb.Length > 0 && (valueSbString[valueSbString.Length -
                1] == 0x20 || valueSbString[valueSbString.Length - 1] == 0x09);
                    string encodedText = (endsWithSpace ? String.Empty : " ") +
                    Rfc2047.EncodeString(addrSpec) + " :;";
                    sb.Append(encodedText);
                    }
                    lastIndex = endIndex;
                    }
                    ++groupIndex;
                  }

                  break;
                }
                }
                  }
                  sb.Append(str.Substring(lastIndex, str.Length - lastIndex));
                  str = sb.ToString();
                }
                return str;
            }
Beispiel #35
0
 public void Colon()
 {
     Assert.AreEqual(Token.Colon(), Tokener.Tokenize(":").First());
 }
Beispiel #36
0
 public void RightParenthesis()
 {
     Assert.AreEqual(Token.RightParenthesis(), Tokener.Tokenize(")").First());
 }
Beispiel #37
0
 public void StringReader()
 {
     Assert.AreEqual(new[] { Token.Integer("123"), Token.Comma(), Token.Char('*'), Token.Eoi() },
                     Tokener.Tokenize(new StringReader("123,*")).ToArray());
 }