protected override Stream OpenValueReadStream(out int skipTrailingNulls) { TnefPropertyType tnefType = this.PropertyReader.PropertyTag.TnefType; TnefPropertyType tnefPropertyType = tnefType; switch (tnefPropertyType) { case TnefPropertyType.String8: { skipTrailingNulls = 1; TextToText textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly); textToText.InputEncoding = this.GetString8Encoding(); textToText.OutputEncoding = ConvertUtils.UnicodeEncoding; return(new ConverterStream(this.PropertyReader.GetRawValueReadStream(), textToText, ConverterStreamAccess.Read)); } case TnefPropertyType.Unicode: skipTrailingNulls = 2; return(this.PropertyReader.GetRawValueReadStream()); default: if (tnefPropertyType == TnefPropertyType.Binary) { skipTrailingNulls = 0; return(this.PropertyReader.GetRawValueReadStream()); } StorageGlobals.ContextTraceError(ExTraceGlobals.CcInboundTnefTracer, "InboundTnefConverter::StreamLargeProperty: only supports binary and string properties."); throw new ConversionFailedException(ConversionFailureReason.CorruptContent); } }
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 TestHeaderAndFooter() { string expected = "Header,Footer"; string text = ","; var converter = new TextToText { Header = "Header", Footer = "Footer" }; var result = converter.Convert(text); Assert.AreEqual(expected, result); }
public void TestSimpleTextToText() { string expected = "This is some sample text. This is line #1." + Environment.NewLine + "This is line #2." + Environment.NewLine + "And this is line #3." + Environment.NewLine; string text = "This is some sample text. This is line #1." + Environment.NewLine + "This is line #2." + Environment.NewLine + "And this is line #3." + Environment.NewLine; var converter = new TextToText(); var result = converter.Convert(text); Assert.AreEqual(expected, result); }
public void TestDefaultPropertyValues() { var converter = new TextToText(); Assert.IsFalse(converter.DetectEncodingFromByteOrderMark, "DetectEncodingFromByteOrderMark"); Assert.IsNull(converter.Footer, "Footer"); Assert.IsNull(converter.Header, "Header"); Assert.AreEqual(Encoding.UTF8, converter.InputEncoding, "InputEncoding"); Assert.AreEqual(TextFormat.Text, converter.InputFormat, "InputFormat"); Assert.AreEqual(Encoding.UTF8, converter.OutputEncoding, "OutputEncoding"); Assert.AreEqual(TextFormat.Text, converter.OutputFormat, "OutputFormat"); Assert.AreEqual(4096, converter.InputStreamBufferSize, "InputStreamBufferSize"); Assert.AreEqual(4096, converter.OutputStreamBufferSize, "OutputStreamBufferSize"); }
internal Stream ConvertWriteStreamFormat(Stream stream, Charset writeStreamCharset) { if (this.internalFormat == (InternalBodyFormat)this.format && (writeStreamCharset == null || this.charset == writeStreamCharset)) { return(stream); } Charset charset = writeStreamCharset ?? this.charset; TextConverter converter; if (this.internalFormat == InternalBodyFormat.RtfCompressed) { stream = new ConverterStream(stream, new RtfToRtfCompressed(), ConverterStreamAccess.Write); if (BodyFormat.Rtf == this.format) { return(stream); } converter = new TextToRtf { InputEncoding = charset.GetEncoding() }; } else if (this.internalFormat == InternalBodyFormat.Enriched) { converter = new HtmlToEnriched { InputEncoding = charset.GetEncoding(), OutputEncoding = this.Encoding }; } else if (this.internalFormat == InternalBodyFormat.Html) { converter = new HtmlToHtml { InputEncoding = charset.GetEncoding(), OutputEncoding = this.Encoding }; } else { converter = new TextToText { InputEncoding = charset.GetEncoding(), OutputEncoding = this.Encoding }; } return(new ConverterStream(stream, converter, ConverterStreamAccess.Write)); }
public void TestConvertFromStreamToStream() { const string input = "This is some text..."; var converter = new TextToText { DetectEncodingFromByteOrderMark = false, InputEncoding = Encoding.ASCII, OutputEncoding = Encoding.ASCII }; using (var output = new MemoryStream()) { using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(input))) converter.Convert(stream, output); var result = Encoding.ASCII.GetString(output.GetBuffer(), 0, (int)output.Length); Assert.AreEqual(input, result); } }
public void TestConvertFromStreamToWriter() { const string input = "This is some text..."; var converter = new TextToText { DetectEncodingFromByteOrderMark = false, InputEncoding = Encoding.ASCII, OutputEncoding = Encoding.ASCII }; using (var writer = new StringWriter()) { using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(input))) converter.Convert(stream, writer); var result = writer.ToString(); Assert.AreEqual(input, result); } }
private static object FromTextToText(ICoreItem coreItem, BodyWriteConfiguration configuration, Stream bodyStream, bool createWriter) { Stream stream = null; object obj = null; try { stream = new BodyCharsetDetectionStream(bodyStream, null, coreItem, BodyStreamFormat.Text, ConvertUtils.UnicodeCharset, configuration.TargetCharset, configuration.TargetCharsetFlags, null, false); if (!createWriter && !configuration.IsContentTransformationNeeded(coreItem)) { obj = stream; } else { TextToText textToText; if (string.IsNullOrEmpty(configuration.InjectPrefix) && string.IsNullOrEmpty(configuration.InjectSuffix)) { textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly); } else { textToText = new TextToText(); } textToText.InputEncoding = configuration.SourceEncoding; textToText.OutputEncoding = ConvertUtils.UnicodeEncoding; if (!string.IsNullOrEmpty(configuration.InjectPrefix) || !string.IsNullOrEmpty(configuration.InjectSuffix)) { textToText.Header = configuration.InjectPrefix; textToText.Footer = configuration.InjectSuffix; textToText.HeaderFooterFormat = configuration.InjectionHeaderFooterFormat; } obj = BodyWriteDelegates.GetConverterStreamOrWriter(stream, textToText, createWriter); } } finally { if (obj == null && stream != null) { BodyWriteDelegates.SafeDisposeStream(stream); } } return(obj); }
public void TestArgumentExceptions() { var converter = new TextToText(); Assert.Throws <ArgumentNullException> (() => converter.InputEncoding = null); Assert.Throws <ArgumentNullException> (() => converter.OutputEncoding = null); Assert.Throws <ArgumentOutOfRangeException> (() => converter.InputStreamBufferSize = -1); Assert.Throws <ArgumentOutOfRangeException> (() => converter.OutputStreamBufferSize = -1); Assert.Throws <ArgumentNullException> (() => converter.Convert(null)); Assert.Throws <ArgumentNullException> (() => converter.Convert((Stream)null, Stream.Null)); Assert.Throws <ArgumentNullException> (() => converter.Convert(Stream.Null, (Stream)null)); Assert.Throws <ArgumentNullException> (() => converter.Convert((TextReader)null, Stream.Null)); Assert.Throws <ArgumentNullException> (() => converter.Convert(Stream.Null, (TextWriter)null)); Assert.Throws <ArgumentNullException> (() => converter.Convert(new StreamReader(Stream.Null), (Stream)null)); Assert.Throws <ArgumentNullException> (() => converter.Convert((Stream)null, new StreamWriter(Stream.Null))); Assert.Throws <ArgumentNullException> (() => converter.Convert(new StreamReader(Stream.Null), (TextWriter)null)); Assert.Throws <ArgumentNullException> (() => converter.Convert((TextReader)null, new StreamWriter(Stream.Null))); }
public void TestPropertySetters() { var latin1 = Encoding.GetEncoding("iso-8859-1"); var utf16 = Encoding.Unicode; var converter = new TextToText(); converter.InputEncoding = latin1; Assert.AreEqual(latin1, converter.InputEncoding, "InputEncoding"); converter.InputStreamBufferSize = 5000; Assert.AreEqual(5000, converter.InputStreamBufferSize, "InputStreamBufferSize"); converter.OutputEncoding = utf16; Assert.AreEqual(utf16, converter.OutputEncoding, "OutputEncoding"); converter.OutputStreamBufferSize = 6000; Assert.AreEqual(6000, converter.OutputStreamBufferSize, "OutputStreamBufferSize"); converter.DetectEncodingFromByteOrderMark = true; Assert.IsTrue(converter.DetectEncodingFromByteOrderMark, "DetectEncodingFromByteOrderMark"); }
private static object FromTextToText(ICoreItem coreItem, BodyReadConfiguration configuration, Stream bodyStream, bool createReader) { TextToText textToText; if (string.IsNullOrEmpty(configuration.InjectPrefix) && string.IsNullOrEmpty(configuration.InjectSuffix)) { textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly); } else { textToText = new TextToText(); } textToText.InputEncoding = ConvertUtils.UnicodeEncoding; textToText.OutputEncoding = configuration.Encoding; if (!string.IsNullOrEmpty(configuration.InjectPrefix) || !string.IsNullOrEmpty(configuration.InjectSuffix)) { textToText.Header = configuration.InjectPrefix; textToText.Footer = configuration.InjectSuffix; textToText.HeaderFooterFormat = configuration.InjectionHeaderFooterFormat; } return(BodyReadDelegates.GetTextStreamOrReader(bodyStream, textToText, createReader)); }
static public void AddFooterToBody(String messageid, Microsoft.Exchange.Data.Transport.Email.Body body, String text) { Stream originalbodycontent = null; Stream newbodycontent = null; Encoding encoding; String charsetname; Log log = Log.Instance; try { BodyFormat bodyformat = body.BodyFormat; if (!body.TryGetContentReadStream(out originalbodycontent)) { //body can't be decoded log.Do(messageid + ": email body format could not be decoded - warning footer not appended", 0); } if (BodyFormat.Text == bodyformat) { charsetname = body.CharsetName; if (null == charsetname || !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetname, out encoding)) { // either no charset, or charset is not supported by the system log.Do(messageid + ": email body character set is either not defined or not supported by the system - warning footer not appended", 0); } else { TextToText texttotextconversion = new TextToText(); texttotextconversion.InputEncoding = encoding; texttotextconversion.HeaderFooterFormat = HeaderFooterFormat.Text; texttotextconversion.Footer = text; newbodycontent = body.GetContentWriteStream(); try { texttotextconversion.Convert(originalbodycontent, newbodycontent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { log.Do(messageid + ": error while performing body text conversion - warning footer not appended", 0); } } } else if (BodyFormat.Html == bodyformat) { charsetname = body.CharsetName; if (null == charsetname || !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetname, out encoding)) { log.Do(messageid + ": email body character set is either not defined or unsupported - warning footer not appended", 0); } else { HtmlToHtml htmltohtmlconversion = new HtmlToHtml(); htmltohtmlconversion.InputEncoding = encoding; htmltohtmlconversion.HeaderFooterFormat = HeaderFooterFormat.Html; htmltohtmlconversion.Footer = "<p><font size=\"-1\">" + text + "</font></p>"; newbodycontent = body.GetContentWriteStream(); try { htmltohtmlconversion.Convert(originalbodycontent, newbodycontent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { // the conversion has failed.. log.Do(messageid + ": error while performing body html conversion - warning footer not appended", 0); } } } else if (BodyFormat.Rtf == bodyformat) { RtfToRtf rtftortfconversion = new RtfToRtf(); rtftortfconversion.HeaderFooterFormat = HeaderFooterFormat.Html; rtftortfconversion.Footer = "<font face=\"Arial\" size=\"+1\">" + text + "</font>"; Stream uncompressedbodycontent = body.GetContentWriteStream(); try { rtftortfconversion.Convert(originalbodycontent, uncompressedbodycontent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { //Conversion failed log.Do(messageid + ": error while decompressing body rtf - warning footer not appended", 0); } RtfToRtfCompressed rtfcompressionconversion = new RtfToRtfCompressed(); rtfcompressionconversion.CompressionMode = RtfCompressionMode.Compressed; newbodycontent = body.GetContentWriteStream(); try { rtfcompressionconversion.Convert(uncompressedbodycontent, newbodycontent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { // the conversion has failed.. log.Do(messageid + ": error compressing body rtf - warning footer not appended", 0); } } else { // Handle cases where the body format is not one of the above. log.Do(messageid + ": unsupported body email format - warning footer not appended", 0); } } finally { if (originalbodycontent != null) { originalbodycontent.Close(); } if (newbodycontent != null) { newbodycontent.Close(); } } }
/// <summary> /// Invoked by Exchange when the entire message has been received. /// </summary> /// <param name="source">The source of this event.</param> /// <param name="eodArgs">The arguments for this event.</param> public void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs eodArgs) { Debug.WriteLine("[BodyConversion] OnEndOfDataHandler is called"); // The purpose of this sample is to show how TextConverters can be used // to update the body. This sample shows how to ensure that no active // content, such as scripts, can pass through in a message body. EmailMessage message = eodArgs.MailItem.Message; Stream originalBodyContent = null; Stream newBodyContent = null; Encoding encoding; string charsetName; try { Body body = message.Body; BodyFormat bodyFormat = body.BodyFormat; if (!body.TryGetContentReadStream(out originalBodyContent)) { // You cannot decode the body. return; } if (BodyFormat.Text == bodyFormat) { // Plain text body. Add a disclaimer to this body. charsetName = body.CharsetName; if (null == charsetName || !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding)) { // Either no charset, or charset is not supported by the system. return; } // Create and set up the TextToText conversion object. TextToText textToTextConversion = new TextToText(); // Don't change the body code page. textToTextConversion.InputEncoding = encoding; // By default, the output code page is the same as the input code page. // Add a disclaimer to indicate that the body is not being filtered. textToTextConversion.HeaderFooterFormat = HeaderFooterFormat.Text; textToTextConversion.Footer = "the plain text body is NOT being filtered"; // Open the stream to write updated content into. newBodyContent = body.GetContentWriteStream(); // Do the conversion. This will replace the original text. // with an updated version. try { // The easiest way to do the conversion in one step is by using the Convert // method. It creates the appropriate converter stream // and copies from one stream to another. textToTextConversion.Convert(originalBodyContent, newBodyContent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { // The conversion has failed. } } else if (BodyFormat.Html == bodyFormat) { // The HTML body. // Filter the original HTML to remove any scripts and other // potentially unsafe content. charsetName = body.CharsetName; if (null == charsetName || !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding)) { // Either no charset, or charset is not supported by the system. return; } // Create and set up the HtmlToHtml conversion object. HtmlToHtml htmlToHtmlConversion = new HtmlToHtml(); // Don't change the body code page. htmlToHtmlConversion.InputEncoding = encoding; // By default, the output code page is the same as the input code page. // Set up output HTML filtering. HTML filtering will ensure that // no scripts or active content can pass through. htmlToHtmlConversion.FilterHtml = true; // Add a disclaimer to indicate that the body is being filtered. htmlToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html; htmlToHtmlConversion.Footer = "<p><font face=\"Arial\" size=\"+1\">the HTML body is being filtered</font></p>"; // Open the stream to write updated content into. newBodyContent = body.GetContentWriteStream(); // Do the conversion. This will replace the original HTML // with a filtered version. try { // The easiest way to do the conversion in one step is by using the Convert // method. It creates an appropriate converter stream // and copies from one stream to another. htmlToHtmlConversion.Convert(originalBodyContent, newBodyContent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { // The conversion has failed. } } else if (BodyFormat.Rtf == bodyFormat) { // This is compressed RTF body in a TNEF message. // Compressed RTF body can contain the encapsulated original HTML to be // filtered. // Do not modify the message format here, just filter out // potentially unsafe content. Convert RTF to HTML, filter out any // unsafe HTML content, and convert the result back to RTF. // Note that conversion from RTF to HTML and back to RTF can result in loss of data. Some // embedded images in RTF can be lost and formatting can slightly change. // First wrap the original body content, which is in a "compressed RTF" format, into // a stream that will do RTF decompression. Reading from this stream // will return original RTF (the same format that the Word and RichEdit controls are using). ConverterStream uncompressedRtf = new ConverterStream(originalBodyContent, new RtfCompressedToRtf(), ConverterStreamAccess.Read); // Create and configure the RtfToHtml conversion object. RtfToHtml rtfToHtmlConversion = new RtfToHtml(); // Set up output HTML filtering. HTML filtering will ensure that // no scripts or active content can pass through. rtfToHtmlConversion.FilterHtml = true; // Add a disclaimer to indicate that the body is being filtered. rtfToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html; rtfToHtmlConversion.Footer = "<p><font face=\"Arial\" size=1>the RTF body is being filtered</font></p>"; // Now create a wrapping TextReader object, which returns the filtered // HTML converted (or extracted) from the original RTF. ConverterReader html = new ConverterReader(uncompressedRtf, rtfToHtmlConversion); // After you filter the HTML, convert it back to RTF. For the purposes of this sample, do not // change the message format. // Create and configure the HtmlToRtf conversion object. HtmlToRtf htmlToRtfConversion = new HtmlToRtf(); // Create a wrapping stream that returns RTF converted back from filtered HTML. ConverterStream filteredRtf = new ConverterStream(html, htmlToRtfConversion); // Create and configure the RtfToRtfCompressed conversion object, which // will compress the resulting RTF. RtfToRtfCompressed rtfCompressionConversion = new RtfToRtfCompressed(); // Always write it back in a compressed form. rtfCompressionConversion.CompressionMode = RtfCompressionMode.Compressed; // Open the stream to write updated body content into. newBodyContent = body.GetContentWriteStream(); // Finally, perform the complete chain of conversions you set up. This // will read the original compressed RTF chunk by chunk, convert it to HTML // and filter scripts, then convert HTML back to RTF, compress it and write // back into the current message body. try { // Use the Convert method because it is convenient. This Convert // method compresses the resulting RTF it reads from the conversion // chain stream you set up and writes the result into the output stream. // It saves a few lines of code that would be required to create another wrapper stream and // copy from one stream to another. rtfCompressionConversion.Convert(filteredRtf, newBodyContent); } catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException) { // The conversion has failed. } } else { // Handle cases where the body format is not one of the above. } } finally { if (originalBodyContent != null) { originalBodyContent.Close(); } if (newBodyContent != null) { newBodyContent.Close(); } } }
public override Stream OpenReadStream(long start, long end) { base.ThrowIfDisposed(); BodyFormatConversionStorage.BodyFormatConversion conversion = BodyFormatConversionStorage.GetConversion(this.originalFormat, this.targetFormat); TextConverter converter = null; Encoding inputEncoding = null; if (this.originalCharset != null) { inputEncoding = this.originalCharset.GetEncoding(); } Encoding outputEncoding = null; if (this.targetCharset != null) { outputEncoding = this.targetCharset.GetEncoding(); } Stream stream = this.originalStorage.OpenReadStream(this.originalStart, this.originalEnd); switch (conversion) { case BodyFormatConversionStorage.BodyFormatConversion.HtmlToText: converter = new HtmlToText { InputEncoding = inputEncoding, OutputEncoding = outputEncoding }; break; case BodyFormatConversionStorage.BodyFormatConversion.HtmlToEnriched: converter = new HtmlToEnriched { InputEncoding = inputEncoding, OutputEncoding = outputEncoding }; break; case BodyFormatConversionStorage.BodyFormatConversion.RtfCompressedToText: stream = new ConverterStream(stream, new RtfCompressedToRtf(), ConverterStreamAccess.Read); converter = new RtfToText { OutputEncoding = outputEncoding }; break; case BodyFormatConversionStorage.BodyFormatConversion.TextToText: converter = new TextToText { InputEncoding = inputEncoding, OutputEncoding = outputEncoding }; break; case BodyFormatConversionStorage.BodyFormatConversion.HtmlToHtml: converter = new HtmlToHtml { InputEncoding = inputEncoding, OutputEncoding = outputEncoding }; break; case BodyFormatConversionStorage.BodyFormatConversion.EnrichedToText: converter = new EnrichedToText { InputEncoding = inputEncoding, OutputEncoding = outputEncoding }; break; } return(new ConverterStream(stream, converter, ConverterStreamAccess.Read)); }