Exemplo n.º 1
0
        public void TestSmtpDataFilterBufferBoundaryNonNewLineEnsureNewLine()
        {
            string output = new string ('x', 72) + ".hello\r\n";
            var    filter = new SmtpDataFilter();

            using (var memory = new MemoryStream()) {
                byte[] buffer;
                int    n;

                using (var filtered = new FilteredStream(memory)) {
                    filtered.Add(filter);

                    buffer = Encoding.ASCII.GetBytes(new string ('x', 72));
                    filtered.Write(buffer, 0, buffer.Length);

                    buffer = Encoding.ASCII.GetBytes(".hello");
                    filtered.Write(buffer, 0, buffer.Length);

                    filtered.Flush();
                }

                buffer = memory.GetBuffer();
                n      = (int)memory.Length;

                var text = Encoding.ASCII.GetString(buffer, 0, n);

                Assert.AreEqual(output, text);
            }
        }
Exemplo n.º 2
0
        public void TestArmoredFromFilter()
        {
            const string text     = "This text is meant to test that the filter will armor lines beginning with\nFrom (like mbox). And let's add another\nFrom line for good measure, shall we?\n";
            const string expected = "This text is meant to test that the filter will armor lines beginning with\n=46rom (like mbox). And let's add another\n=46rom line for good measure, shall we?\n";
            var          filter   = new ArmoredFromFilter();

            TestArgumentExceptions(filter);

            using (var stream = new MemoryStream()) {
                using (var filtered = new FilteredStream(stream)) {
                    int fromIndex = text.IndexOf("\nFrom ", StringComparison.Ordinal);
                    var buffer    = Encoding.UTF8.GetBytes(text);

                    filtered.Add(filter);

                    // write out a buffer where the end boundary falls in the middle of "From "
                    int endIndex = fromIndex + 3;
                    filtered.Write(buffer, 0, endIndex);

                    // write out the rest
                    filtered.Write(buffer, endIndex, buffer.Length - endIndex);
                    filtered.Flush();

                    var actual = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);

                    Assert.AreEqual(expected, actual, "From armoring failed when end boundary falls in the middle of From.");
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the <see cref="MimeKit.HeaderList"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Writes all of the headers to the output stream.
        /// </remarks>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="options"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        /// The operation was canceled via the cancellation token.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        public void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            cancellationToken.ThrowIfCancellationRequested();

            using (var filtered = new FilteredStream(stream)) {
                filtered.Add(options.CreateNewLineFilter());

                foreach (var header in headers)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var name = Encoding.ASCII.GetBytes(header.Field);

                    filtered.Write(name, 0, name.Length);
                    filtered.WriteByte((byte)':');
                    filtered.Write(header.RawValue, 0, header.RawValue.Length);
                }

                filtered.Flush();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Writes the message to the specified stream.
        /// </summary>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The stream.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="options"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// </exception>
        public void WriteTo(FormatOptions options, Stream stream)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!Headers.Contains("Date"))
            {
                Date = DateTimeOffset.Now;
            }

            if (messageId == null)
            {
                MessageId = MimeUtils.GenerateMessageId();
            }

            if (version == null && Body != null && Body.Headers.Count > 0)
            {
                MimeVersion = new Version(1, 0);
            }

            if (Body == null)
            {
                Headers.WriteTo(stream);

                stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length);
            }
            else
            {
                using (var filtered = new FilteredStream(stream)) {
                    filtered.Add(options.CreateNewLineFilter());

                    foreach (var header in MergeHeaders())
                    {
                        var name = Encoding.ASCII.GetBytes(header.Field);

                        filtered.Write(name, 0, name.Length);
                        filtered.WriteByte((byte)':');
                        filtered.Write(header.RawValue, 0, header.RawValue.Length);
                    }

                    filtered.Flush();
                }

                options.WriteHeaders = false;
                Body.WriteTo(options, stream);
            }
        }
Exemplo n.º 5
0
        public void TestSmtpDataFilterEnsureNewLine()
        {
            var inputs  = new string[] { SimpleDataInput.TrimEnd(), ComplexDataInput.TrimEnd() };
            var outputs = new string[] { SimpleDataInput, ComplexDataOutput };
            var filter  = new SmtpDataFilter();

            for (int i = 0; i < inputs.Length; i++)
            {
                using (var memory = new MemoryStream()) {
                    byte[] buffer;
                    int    n;

                    using (var filtered = new FilteredStream(memory)) {
                        filtered.Add(filter);

                        buffer = Encoding.ASCII.GetBytes(inputs[i]);
                        filtered.Write(buffer, 0, buffer.Length);
                        filtered.Flush();
                    }

                    buffer = memory.GetBuffer();
                    n      = (int)memory.Length;

                    var text = Encoding.ASCII.GetString(buffer, 0, n);

                    Assert.AreEqual(outputs[i], text);

                    filter.Reset();
                }
            }
        }
Exemplo n.º 6
0
        void TestDecoder(ContentEncoding encoding, byte[] rawData, string encodedFile, int bufferSize)
        {
            int n;

            using (var original = new MemoryStream(rawData, false)) {
                using (var decoded = new MemoryStream()) {
                    using (var filtered = new FilteredStream(decoded)) {
                        filtered.Add(DecoderFilter.Create(encoding));

                        using (var file = File.OpenRead(Path.Combine(dataDir, encodedFile))) {
                            var buffer = new byte[bufferSize];

                            while ((n = file.Read(buffer, 0, bufferSize)) > 0)
                            {
                                filtered.Write(buffer, 0, n);
                            }
                        }

                        filtered.Flush();
                    }

                    var buf = decoded.GetBuffer();
                    n = rawData.Length;

                    Assert.AreEqual(rawData.Length, decoded.Length, "Decoded length is incorrect.");

                    for (int i = 0; i < n; i++)
                    {
                        Assert.AreEqual(rawData[i], buf[i], "The byte at offset {0} does not match.", i);
                    }
                }
            }
        }
Exemplo n.º 7
0
        void TestEncoder(ContentEncoding encoding, byte[] rawData, string encodedFile, int bufferSize)
        {
            int n;

            using (var original = new MemoryStream()) {
                using (var file = File.OpenRead(Path.Combine(dataDir, encodedFile))) {
                    using (var filtered = new FilteredStream(original)) {
                        filtered.Add(new Dos2UnixFilter());
                        file.CopyTo(filtered, 4096);
                        filtered.Flush();
                    }
                }

                using (var encoded = new MemoryStream()) {
                    if (encoding == ContentEncoding.UUEncode)
                    {
                        var begin = Encoding.ASCII.GetBytes("begin 644 photo.jpg\n");
                        encoded.Write(begin, 0, begin.Length);
                    }

                    using (var filtered = new FilteredStream(encoded)) {
                        filtered.Add(EncoderFilter.Create(encoding));

                        using (var memory = new MemoryStream(rawData, false)) {
                            var buffer = new byte[bufferSize];

                            while ((n = memory.Read(buffer, 0, bufferSize)) > 0)
                            {
                                filtered.Write(buffer, 0, n);
                            }
                        }

                        filtered.Flush();
                    }

                    if (encoding == ContentEncoding.UUEncode)
                    {
                        var end = Encoding.ASCII.GetBytes("end\n");
                        encoded.Write(end, 0, end.Length);
                    }

                    var buf0 = original.GetBuffer();
                    var buf1 = encoded.GetBuffer();
                    n = (int)original.Length;

                    Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect.");

                    for (int i = 0; i < n; i++)
                    {
                        Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i);
                    }
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Writes the <see cref="MimeKit.HeaderList"/> to the specified output stream.
        /// </summary>
        /// <remarks>
        /// Writes all of the headers to the output stream.
        /// </remarks>
        /// <param name="options">The formatting options.</param>
        /// <param name="stream">The output stream.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="options"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        /// The operation was canceled via the cancellation token.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        public void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            using (var filtered = new FilteredStream(stream)) {
                if (options.NewLineFormat != FormatOptions.Default.NewLineFormat)
                {
                    filtered.Add(options.CreateNewLineFilter());
                }

                foreach (var header in headers)
                {
                    var    name = Encoding.ASCII.GetBytes(header.Field);
                    byte[] rawValue;

                    filtered.Write(name, 0, name.Length, cancellationToken);
                    filtered.Write(new [] { (byte)':' }, 0, 1, cancellationToken);

                    if (options.International)
                    {
                        rawValue = header.GetRawValue(options, Encoding.UTF8);
                    }
                    else
                    {
                        rawValue = header.RawValue;
                    }

                    filtered.Write(rawValue, 0, rawValue.Length, cancellationToken);
                }

                filtered.Flush(cancellationToken);
            }
        }
Exemplo n.º 9
0
        Stream GetResponseStream(ImapReplayCommand command)
        {
            MemoryStream memory;

            if (testUnixFormat)
            {
                memory = new MemoryStream();

                using (var filtered = new FilteredStream(memory)) {
                    filtered.Add(new Dos2UnixFilter());
                    filtered.Write(command.Response, 0, command.Response.Length);
                    filtered.Flush();
                }

                memory.Position = 0;
            }
            else
            {
                memory = new MemoryStream(command.Response, false);
            }

            return(memory);
        }
Exemplo n.º 10
0
        public void TestCanReadWriteSeekTimeout()
        {
            var buffer = new byte[1024];

            using (var filtered = new FilteredStream(new CanReadWriteSeekStream(true, false, false, false))) {
                Assert.IsTrue(filtered.CanRead);
                Assert.IsFalse(filtered.CanWrite);
                Assert.IsFalse(filtered.CanSeek);
                Assert.IsFalse(filtered.CanTimeout);

                Assert.Throws <NotImplementedException> (() => filtered.Read(buffer, 0, buffer.Length));
                Assert.Throws <NotSupportedException> (() => filtered.Write(buffer, 0, buffer.Length));
                Assert.Throws <NotSupportedException> (() => filtered.Seek(0, SeekOrigin.End));
            }

            using (var filtered = new FilteredStream(new CanReadWriteSeekStream(false, true, false, false))) {
                Assert.IsFalse(filtered.CanRead);
                Assert.IsTrue(filtered.CanWrite);
                Assert.IsFalse(filtered.CanSeek);
                Assert.IsFalse(filtered.CanTimeout);

                Assert.Throws <NotSupportedException> (() => filtered.Read(buffer, 0, buffer.Length));
                Assert.Throws <NotImplementedException> (() => filtered.Write(buffer, 0, buffer.Length));
                Assert.Throws <NotSupportedException> (() => filtered.Seek(0, SeekOrigin.End));
            }

            using (var filtered = new FilteredStream(new CanReadWriteSeekStream(false, false, true, false))) {
                Assert.IsFalse(filtered.CanRead);
                Assert.IsFalse(filtered.CanWrite);
                Assert.IsFalse(filtered.CanSeek);                   // FilteredStream can never seek
                Assert.IsFalse(filtered.CanTimeout);

                Assert.Throws <NotSupportedException> (() => filtered.Read(buffer, 0, buffer.Length));
                Assert.Throws <NotSupportedException> (() => filtered.Write(buffer, 0, buffer.Length));
                Assert.Throws <NotSupportedException> (() => filtered.Seek(0, SeekOrigin.End));                 // FilteredStream can never seek
            }
        }
Exemplo n.º 11
0
        static void TestOpenPgpBlockFilter(OpenPgpBlockFilter filter, byte[] buffer, string expected, int increment)
        {
            using (var stream = new MemoryStream()) {
                using (var filtered = new FilteredStream(stream)) {
                    int startIndex = 0;

                    filtered.Add(filter);

                    while (startIndex < buffer.Length)
                    {
                        int n = Math.Min(buffer.Length - startIndex, increment);

                        filtered.Write(buffer, startIndex, n);
                        startIndex += n;
                    }

                    filtered.Flush();

                    var actual = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);

                    Assert.AreEqual(expected, actual, "increment of {0} failed.", increment);
                }
            }
        }
Exemplo n.º 12
0
        public void TestBestEncodingFilter()
        {
            const string fromLines = "This text is meant to test that the filter will armor lines beginning with\nFrom (like mbox).\n";
            const string ascii     = "This is some ascii text to make sure that\nthe filter returns 7bit encoding...\n";
            const string french    = "Wikipédia est un projet d’encyclopédie collective en ligne, universelle, multilingue et fonctionnant sur le principe du wiki. Wikipédia a pour objectif d’offrir un contenu librement réutilisable, objectif et vérifiable, que chacun peut modifier et améliorer.\n\nTous les rédacteurs des articles de Wikipédia sont bénévoles. Ils coordonnent leurs efforts au sein d'une communauté collaborative, sans dirigeant.";
            var          filter    = new BestEncodingFilter();

            TestArgumentExceptions(filter);

            Assert.Throws <ArgumentOutOfRangeException> (() => filter.GetBestEncoding(EncodingConstraint.SevenBit, 10));

            // Test ASCII text
            using (var stream = new MemoryStream()) {
                using (var filtered = new FilteredStream(stream)) {
                    var             buffer = Encoding.UTF8.GetBytes(ascii);
                    ContentEncoding encoding;

                    Assert.IsFalse(filtered.CanTimeout, "CanTimeout");
                    Assert.Throws <InvalidOperationException> (() => { var x = filtered.ReadTimeout; });
                    Assert.Throws <InvalidOperationException> (() => { var x = filtered.WriteTimeout; });
                    Assert.Throws <InvalidOperationException> (() => filtered.ReadTimeout  = 50);
                    Assert.Throws <InvalidOperationException> (() => filtered.WriteTimeout = 50);
                    Assert.Throws <NotSupportedException> (() => { long x = filtered.Length; });
                    Assert.Throws <NotSupportedException> (() => filtered.SetLength(100));
                    Assert.Throws <NotSupportedException> (() => { long x = filtered.Position; });
                    Assert.Throws <NotSupportedException> (() => filtered.Position = 0);

                    Assert.Throws <ArgumentNullException> (() => filtered.Add(null));
                    Assert.Throws <ArgumentNullException> (() => filtered.Contains(null));
                    Assert.Throws <ArgumentNullException> (() => filtered.Remove(null));

                    filtered.Add(filter);

                    Assert.IsTrue(filtered.Contains(filter), "Contains");

                    filtered.Write(buffer, 0, buffer.Length);
                    filtered.Flush();

                    encoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                    Assert.AreEqual(ContentEncoding.SevenBit, encoding, "ASCII 7bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    Assert.AreEqual(ContentEncoding.SevenBit, encoding, "ASCII 8bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.None);
                    Assert.AreEqual(ContentEncoding.SevenBit, encoding, "ASCII no constraint.");

                    Assert.IsTrue(filtered.Remove(filter), "Remove");
                }
            }

            filter.Reset();

            // Test ASCII text with a line beginning with "From "
            using (var stream = new MemoryStream()) {
                using (var filtered = new FilteredStream(stream)) {
                    int             fromIndex = fromLines.IndexOf("\nFrom ", StringComparison.Ordinal);
                    var             buffer    = Encoding.UTF8.GetBytes(fromLines);
                    ContentEncoding encoding;

                    filtered.Add(filter);

                    // write out a buffer where the end boundary falls in the middle of "From "
                    int endIndex = fromIndex + 3;
                    filtered.Write(buffer, 0, endIndex);

                    // write out the rest
                    filtered.Write(buffer, endIndex, buffer.Length - endIndex);
                    filtered.Flush();

                    encoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "From-line 7bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "From-line 8bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.None);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "From-line no constraint.");
                }
            }

            filter.Reset();

            // Test some French Latin1 text
            using (var stream = new MemoryStream()) {
                using (var filtered = new FilteredStream(stream)) {
                    var             buffer = Encoding.UTF8.GetBytes(french);
                    ContentEncoding encoding;

                    filtered.Add(filter);

                    // We'll write only 60 chars at first to not exceed the 78 char max
                    filtered.Write(buffer, 0, 60);
                    filtered.Flush();

                    encoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "French 7bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    Assert.AreEqual(ContentEncoding.EightBit, encoding, "French 8bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.None);
                    Assert.AreEqual(ContentEncoding.EightBit, encoding, "French no constraint.");

                    filter.Reset();

                    // write the entire French text this time (longest line exceeds 78 chars)
                    filtered.Write(buffer, 0, buffer.Length);
                    filtered.Flush();

                    encoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "French (long lines) 7bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "French (long lines) 8bit constraint.");

                    encoding = filter.GetBestEncoding(EncodingConstraint.None);
                    Assert.AreEqual(ContentEncoding.QuotedPrintable, encoding, "French (long lines) no constraint.");
                }
            }
        }