public void TestRtfCompressedToRtfByteByByte() { var input = new byte[] { (byte)'-', 0x00, 0x00, 0x00, (byte)'+', 0x00, 0x00, 0x00, (byte)'L', (byte)'Z', (byte)'F', (byte)'u', 0xf1, 0xc5, 0xc7, 0xa7, 0x03, 0x00, (byte)'\n', 0x00, (byte)'r', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'B', (byte)'2', (byte)'\n', 0xf3, (byte)' ', (byte)'h', (byte)'e', (byte)'l', (byte)'\t', 0x00, (byte)' ', (byte)'b', (byte)'w', 0x05, 0xb0, (byte)'l', (byte)'d', (byte)'}', (byte)'\n', 0x80, 0x0f, 0xa0 }; const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n"; var filter = new RtfCompressedToRtf(); int outputIndex, outputLength; byte[] output; using (var memory = new MemoryStream()) { for (int i = 0; i < input.Length; i++) { output = filter.Filter(input, i, 1, out outputIndex, out outputLength); memory.Write(output, outputIndex, outputLength); } output = filter.Flush(input, 0, 0, out outputIndex, out outputLength); memory.Write(output, outputIndex, outputLength); output = memory.ToArray(); } Assert.AreEqual(43, output.Length, "outputLength"); Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32"); Assert.AreEqual(RtfCompressionMode.Compressed, filter.CompressionMode, "ComnpressionMode"); var text = Encoding.ASCII.GetString(output); Assert.AreEqual(expected, text); }
public void TestRtfCompressedToRtfRawByteByByte() { var input = new byte[] { (byte)'.', 0x00, 0x00, 0x00, (byte)'\"', 0x00, 0x00, 0x00, (byte)'M', (byte)'E', (byte)'L', (byte)'A', (byte)' ', 0xdf, 0x12, 0xce, (byte)'{', (byte)'\\', (byte)'r', (byte)'t', (byte)'f', (byte)'1', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'2', (byte)'\\', (byte)'p', (byte)'a', (byte)'r', (byte)'d', (byte)' ', (byte)'t', (byte)'e', (byte)'s', (byte)'t', (byte)'}' }; const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard test}"; var filter = new RtfCompressedToRtf(); int outputIndex, outputLength; byte[] output; using (var memory = new MemoryStream()) { for (int i = 0; i < input.Length; i++) { output = filter.Filter(input, i, 1, out outputIndex, out outputLength); memory.Write(output, outputIndex, outputLength); } output = filter.Flush(input, 0, 0, out outputIndex, out outputLength); memory.Write(output, outputIndex, outputLength); output = memory.ToArray(); } Assert.AreEqual(34, output.Length, "outputLength"); Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32"); Assert.AreEqual(RtfCompressionMode.Uncompressed, filter.CompressionMode, "ComnpressionMode"); var text = Encoding.ASCII.GetString(output); Assert.AreEqual(expected, text); }
private void CreateDetectionStream(BodyStreamFormat format, Charset contentCharset, string extraData, bool trustHtmlMetaTag) { this.detectorCache = new PooledMemoryStream(8192); if (extraData != null) { byte[] bytes = ConvertUtils.UnicodeEncoding.GetBytes(extraData); this.detectorCache.Write(bytes, 0, bytes.Length); } switch (format) { case BodyStreamFormat.Text: { if (contentCharset.CodePage == 1200) { this.detectorConversionStream = new StreamWrapper(this.detectorCache, false); return; } TextToText textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly); textToText.InputEncoding = contentCharset.GetEncoding(); textToText.OutputEncoding = ConvertUtils.UnicodeEncoding; textToText.OutputStreamBufferSize = 1024; textToText.InputStreamBufferSize = 1024; this.detectorConversionStream = new ConverterStream(new StreamWrapper(this.detectorCache, false), textToText, ConverterStreamAccess.Write); return; } case BodyStreamFormat.Html: { HtmlToText htmlToText = new HtmlToText(TextExtractionMode.ExtractText); htmlToText.InputEncoding = contentCharset.GetEncoding(); htmlToText.OutputEncoding = ConvertUtils.UnicodeEncoding; htmlToText.DetectEncodingFromMetaTag = trustHtmlMetaTag; htmlToText.OutputStreamBufferSize = 1024; htmlToText.InputStreamBufferSize = 1024; this.detectorConversionStream = new ConverterStream(new StreamWrapper(this.detectorCache, false), htmlToText, ConverterStreamAccess.Write); return; } case BodyStreamFormat.RtfCompressed: case BodyStreamFormat.RtfUncompressed: { RtfToText rtfToText = new RtfToText(TextExtractionMode.ExtractText); rtfToText.OutputEncoding = ConvertUtils.UnicodeEncoding; rtfToText.OutputStreamBufferSize = 1024; rtfToText.InputStreamBufferSize = 1024; this.detectorConversionStream = new ConverterStream(new StreamWrapper(this.detectorCache, false), rtfToText, ConverterStreamAccess.Write); if (format == BodyStreamFormat.RtfCompressed) { RtfCompressedToRtf rtfCompressedToRtf = new RtfCompressedToRtf(); rtfCompressedToRtf.OutputStreamBufferSize = 1024; rtfCompressedToRtf.InputStreamBufferSize = 1024; this.detectorConversionStream = new ConverterStream(this.detectorConversionStream, rtfCompressedToRtf, ConverterStreamAccess.Write); } return; } default: return; } }
public void TestRtfCompressedToRtfInvalidCrc() { var input = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, (byte)'L', (byte)'Z', (byte)'F', (byte)'u', 0xff, 0xff, 0xff, 0xff }; var filter = new RtfCompressedToRtf(); int outputIndex, outputLength; byte[] output; output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength); Assert.AreEqual(0, outputIndex, "outputIndex"); Assert.AreEqual(0, outputLength, "outputLength"); Assert.IsFalse(filter.IsValidCrc32, "IsValidCrc32"); Assert.AreEqual(RtfCompressionMode.Compressed, filter.CompressionMode, "ComnpressionMode"); }
public void TestRtfCompressedToRtfUnknownCompressionType() { var input = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0xff, 0xff, 0xff, 0xff }; var filter = new RtfCompressedToRtf(); int outputIndex, outputLength; byte[] output; output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength); Assert.AreEqual(16, outputIndex, "outputIndex"); Assert.AreEqual(0, outputLength, "outputLength"); Assert.IsFalse(filter.IsValidCrc32, "IsValidCrc32"); Assert.AreEqual((RtfCompressionMode)1145258561, filter.CompressionMode, "ComnpressionMode"); }
public void TestRtfCompressedToRtfRaw() { var input = new byte[] { (byte)'.', 0x00, 0x00, 0x00, (byte)'\"', 0x00, 0x00, 0x00, (byte)'M', (byte)'E', (byte)'L', (byte)'A', (byte)' ', 0xdf, 0x12, 0xce, (byte)'{', (byte)'\\', (byte)'r', (byte)'t', (byte)'f', (byte)'1', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'2', (byte)'\\', (byte)'p', (byte)'a', (byte)'r', (byte)'d', (byte)' ', (byte)'t', (byte)'e', (byte)'s', (byte)'t', (byte)'}' }; const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard test}"; var filter = new RtfCompressedToRtf(); int outputIndex, outputLength; byte[] output; output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength); Assert.AreEqual(16, outputIndex, "outputIndex"); Assert.AreEqual(34, outputLength, "outputLength"); Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32"); Assert.AreEqual(RtfCompressionMode.Uncompressed, filter.CompressionMode, "ComnpressionMode"); var text = Encoding.ASCII.GetString(output, outputIndex, outputLength); Assert.AreEqual(expected, text); }
public void TestCrossingWritePositionExample() { // http://msdn.microsoft.com/en-us/library/ee158471(v=exchg.80).aspx var compressedRtfData = new byte[] { // header 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xe2, 0xd4, 0x4b, 0x51, // data 0x41, 0x00, 0x04, 0x20, 0x57, 0x58, 0x59, 0x5a, 0x0d, 0x6e, 0x7d, 0x01, 0x0e, 0xb0 }; var expected = "{\\rtf1 WXYZWXYZWXYZWXYZWXYZ}"; var converter = new RtfCompressedToRtf(); int outputLength, outputIndex; var decompressed = converter.Flush(compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength); var text = Encoding.UTF8.GetString(decompressed, outputIndex, outputLength); Assert.AreEqual(expected, text, "Decompressed RTF data does not match."); Assert.IsTrue(converter.IsValidCrc32, "Invalid CRC32 checksum."); }
public void TestSimpleCompressedRtfExample() { // http://msdn.microsoft.com/en-us/library/ee217938(v=exchg.80).aspx var compressedRtfData = new byte[] { // header 0x2d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xf1, 0xc5, 0xc7, 0xa7, // data 0x03, 0x00, 0x0a, 0x00, 0x72, 0x63, 0x70, 0x67, 0x31, 0x32, 0x35, 0x42, 0x32, 0x0a, 0xf3, 0x20, 0x68, 0x65, 0x6c, 0x09, 0x00, 0x20, 0x62, 0x77, 0x05, 0xb0, 0x6c, 0x64, 0x7d, 0x0a, 0x80, 0x0f, 0xa0 }; var expected = "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n"; var converter = new RtfCompressedToRtf(); int outputLength, outputIndex; var decompressed = converter.Flush(compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength); var text = Encoding.UTF8.GetString(decompressed, outputIndex, outputLength); Assert.AreEqual(expected, text, "Decompressed RTF data does not match."); Assert.IsTrue(converter.IsValidCrc32, "Invalid CRC32 checksum."); }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; var chars = new char[1024]; var buf = new byte[1024]; while (prop.ReadNextProperty()) { var type = prop.ValueType; object value; switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf(); var content = new MemoryStream(); using (var filtered = new FilteredStream(content)) { filtered.Add(converter); using (var compressed = prop.GetRawValueReadStream()) { compressed.CopyTo(filtered, 4096); filtered.Flush(); } } rtf.Content = new MimeContent(content); content.Position = 0; builder.Attachments.Add(rtf); //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString(); builder.Attachments.Add(html); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString(); builder.Attachments.Add(plain); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.AlternateRecipientAllowed: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MessageClass: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.Importance: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.Priority: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.Sensitivity: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.ClientSubmitTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.SubjectPrefix: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.MessageSubmissionId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.ConversationTopic: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.ConversationIndex: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.SenderName: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.NormalizedSubject: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.CreationTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.LastModificationTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.InternetCPID: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.MessageCodepage: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.INetMailOverrideFormat: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.ReadReceiptRequested: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.OriginatorDeliveryReportRequested: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.TnefCorrelationKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.SenderSearchKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.DeleteAfterSubmit: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MessageDeliveryTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.SentmailEntryId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.RtfInSync: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MappingSignature: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.StoreRecordKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.StoreEntryId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; default: Assert.Throws <ArgumentNullException> (() => prop.ReadTextValue(null, 0, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, -1, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, 0, -1)); Assert.Throws <ArgumentNullException> (() => prop.ReadRawValue(null, 0, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, -1, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, 0, -1)); if (type == typeof(int) || type == typeof(long) || type == typeof(bool) || type == typeof(double) || type == typeof(float)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsString()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } else if (type == typeof(string)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsBoolean()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsDouble()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsFloat()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt16()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt32()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt64()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } try { value = prop.ReadValue(); } catch (Exception ex) { Console.WriteLine("Error in prop.ReadValue(): {0}", ex); value = null; } //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value); Assert.AreEqual(type, value.GetType(), "Unexpected value type for {0}: {1}", prop.PropertyTag, value.GetType().Name); break; } } }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf(); var content = new MemoryStream(); using (var filtered = new FilteredStream(content)) { filtered.Add(converter); using (var compressed = prop.GetRawValueReadStream()) { compressed.CopyTo(filtered, 4096); filtered.Flush(); } } rtf.ContentObject = new ContentObject(content); content.Position = 0; builder.Attachments.Add(rtf); //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString(); builder.Attachments.Add(html); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString(); builder.Attachments.Add(plain); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; default: object value; try { value = prop.ReadValue(); } catch (Exception ex) { Console.WriteLine("Error in prop.ReadValue(): {0}", ex); value = null; } //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value); break; } } }