Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / Mail / WhitespaceReader.cs / 1305376 / WhitespaceReader.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net.Mail
{
using System;
using System.Text;
using System.Net.Mime;
using System.Globalization;
using System.Collections;
using System.Diagnostics;
// FWS, CFWS, and Comments are defined in RFC 2822 section 3.2.3.
//
// FWS is a Folding White Space, or a series of spaces and tabs that may also contain a CRLF.
//
// CFWS is a FWS that also allows for nested comments enclosed in parenthesis. (comment (nested))
//
// Valid values for these are declared in MailBnfHelper.cs and are explained in MailBNF.cs.
//
internal static class WhitespaceReader
{
//
// This skips all folding and whitespace characters
//
// Preconditions:
// - The data string must not be null or empty.
// - The index must be within the upper bounds of the data string.
//
// Return value:
// - The index of the next character that is NOT a whitespace character.
// - -1 if the beginning of the data string is reached.
//
// A FormatException will be thrown if a CR or LF is found NOT in the sequence CRLF.
internal static int ReadFwsReverse(string data, int index)
{
Debug.Assert(!String.IsNullOrEmpty(data), "data was null or empty");
Debug.Assert(index < data.Length, "index was outside the bounds of the string");
bool expectCR = false;
for ( ; index >= 0; index--)
{
// Check for a valid CRLF pair
if (data[index] == MailBnfHelper.CR && expectCR)
{
expectCR = false; // valid pair
}
// LF without CR, or CR without LF, invalid
else if (data[index] == MailBnfHelper.CR || expectCR)
{
throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
}
// LF is only valid if preceded by a CR.
// Skip both if they're found together.
else if (data[index] == MailBnfHelper.LF)
{
expectCR = true;
}
// Skip whitespace
else if (data[index] == MailBnfHelper.Space || data[index] == MailBnfHelper.Tab)
{
// No-op
}
else
{
// Neither check hit so we must be on something that is not whitespace
break;
}
}
if (expectCR)
{
// We found a LF without an immediately preceding CR, invalid.
throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
}
return index;
}
// This method functions similarly to ReadFwsReverse but will also skip any comments.
//
// Comments are text within '(' and ')' and may be nested. There may also be consecutive comments. Unicode is
// allowed, as the comments are not transmitted.
//
// This method was explicitly written in a non-recursive fashion to avoid malicious or accidental
// stack-overflows from user input.
//
// Preconditions:
// - The data string must not be null or empty
// - The index must be within the upper bounds of the data string.
//
// Return value:
// - The given index if it data[index] was not a ')' or white space
// - The index of the next non comment or white space character
// e.g. " d ( ( c o mment) )" returns index 1
// - -1 if skipping the comments and/or whitespace moves you to the beginning of the data string.
// e.g. " (comment) " returns -1
//
// Throws a FormatException for mismatched '(' and ')', or for unescaped characters not allowed in comments.
internal static int ReadCfwsReverse(string data, int index)
{
Debug.Assert(!String.IsNullOrEmpty(data), "data was null or empty");
Debug.Assert(index < data.Length, "index was outside the bounds of the string");
int commentDepth = 0;
// Check for valid whitespace
index = ReadFwsReverse(data, index);
while (index >= 0)
{
// Check for escaped characters. They must be within comments.
int quotedCharCount = QuotedPairReader.CountQuotedChars(data, index, true);
if (commentDepth > 0 && quotedCharCount > 0)
{
index = index - quotedCharCount;
}
// Start a new comment
else if (data[index] == MailBnfHelper.EndComment)
{
commentDepth++;
index--;
}
// Finish a comment
else if (data[index] == MailBnfHelper.StartComment)
{
commentDepth--;
if (commentDepth < 0)
{
// Mismatched '('
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter,
MailBnfHelper.StartComment));
}
index--;
}
// Check for valid characters within comments. Allow Unicode, as we won't transmit any comments.
else if (commentDepth > 0
&& (data[index] > MailBnfHelper.Ascii7bitMaxValue || MailBnfHelper.Ctext[data[index]]))
{
index--;
}
// If we're still in a comment, this must be an invalid char
else if (commentDepth > 0)
{
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter, data[index]));
}
// We must no longer be in a comment, and this is not a whitespace char, return
else
{
break;
}
// Check for valid whitespace
index = ReadFwsReverse(data, index);
}
if (commentDepth > 0)
{
// Mismatched ')', throw
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter, MailBnfHelper.EndComment));
}
return index;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net.Mail
{
using System;
using System.Text;
using System.Net.Mime;
using System.Globalization;
using System.Collections;
using System.Diagnostics;
// FWS, CFWS, and Comments are defined in RFC 2822 section 3.2.3.
//
// FWS is a Folding White Space, or a series of spaces and tabs that may also contain a CRLF.
//
// CFWS is a FWS that also allows for nested comments enclosed in parenthesis. (comment (nested))
//
// Valid values for these are declared in MailBnfHelper.cs and are explained in MailBNF.cs.
//
internal static class WhitespaceReader
{
//
// This skips all folding and whitespace characters
//
// Preconditions:
// - The data string must not be null or empty.
// - The index must be within the upper bounds of the data string.
//
// Return value:
// - The index of the next character that is NOT a whitespace character.
// - -1 if the beginning of the data string is reached.
//
// A FormatException will be thrown if a CR or LF is found NOT in the sequence CRLF.
internal static int ReadFwsReverse(string data, int index)
{
Debug.Assert(!String.IsNullOrEmpty(data), "data was null or empty");
Debug.Assert(index < data.Length, "index was outside the bounds of the string");
bool expectCR = false;
for ( ; index >= 0; index--)
{
// Check for a valid CRLF pair
if (data[index] == MailBnfHelper.CR && expectCR)
{
expectCR = false; // valid pair
}
// LF without CR, or CR without LF, invalid
else if (data[index] == MailBnfHelper.CR || expectCR)
{
throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
}
// LF is only valid if preceded by a CR.
// Skip both if they're found together.
else if (data[index] == MailBnfHelper.LF)
{
expectCR = true;
}
// Skip whitespace
else if (data[index] == MailBnfHelper.Space || data[index] == MailBnfHelper.Tab)
{
// No-op
}
else
{
// Neither check hit so we must be on something that is not whitespace
break;
}
}
if (expectCR)
{
// We found a LF without an immediately preceding CR, invalid.
throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
}
return index;
}
// This method functions similarly to ReadFwsReverse but will also skip any comments.
//
// Comments are text within '(' and ')' and may be nested. There may also be consecutive comments. Unicode is
// allowed, as the comments are not transmitted.
//
// This method was explicitly written in a non-recursive fashion to avoid malicious or accidental
// stack-overflows from user input.
//
// Preconditions:
// - The data string must not be null or empty
// - The index must be within the upper bounds of the data string.
//
// Return value:
// - The given index if it data[index] was not a ')' or white space
// - The index of the next non comment or white space character
// e.g. " d ( ( c o mment) )" returns index 1
// - -1 if skipping the comments and/or whitespace moves you to the beginning of the data string.
// e.g. " (comment) " returns -1
//
// Throws a FormatException for mismatched '(' and ')', or for unescaped characters not allowed in comments.
internal static int ReadCfwsReverse(string data, int index)
{
Debug.Assert(!String.IsNullOrEmpty(data), "data was null or empty");
Debug.Assert(index < data.Length, "index was outside the bounds of the string");
int commentDepth = 0;
// Check for valid whitespace
index = ReadFwsReverse(data, index);
while (index >= 0)
{
// Check for escaped characters. They must be within comments.
int quotedCharCount = QuotedPairReader.CountQuotedChars(data, index, true);
if (commentDepth > 0 && quotedCharCount > 0)
{
index = index - quotedCharCount;
}
// Start a new comment
else if (data[index] == MailBnfHelper.EndComment)
{
commentDepth++;
index--;
}
// Finish a comment
else if (data[index] == MailBnfHelper.StartComment)
{
commentDepth--;
if (commentDepth < 0)
{
// Mismatched '('
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter,
MailBnfHelper.StartComment));
}
index--;
}
// Check for valid characters within comments. Allow Unicode, as we won't transmit any comments.
else if (commentDepth > 0
&& (data[index] > MailBnfHelper.Ascii7bitMaxValue || MailBnfHelper.Ctext[data[index]]))
{
index--;
}
// If we're still in a comment, this must be an invalid char
else if (commentDepth > 0)
{
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter, data[index]));
}
// We must no longer be in a comment, and this is not a whitespace char, return
else
{
break;
}
// Check for valid whitespace
index = ReadFwsReverse(data, index);
}
if (commentDepth > 0)
{
// Mismatched ')', throw
throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter, MailBnfHelper.EndComment));
}
return index;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlSchemaFacet.cs
- AssemblyResourceLoader.cs
- DependencyObjectPropertyDescriptor.cs
- Operator.cs
- SecurityElement.cs
- SpecialFolderEnumConverter.cs
- CommonProperties.cs
- RadioButtonRenderer.cs
- NavigationWindowAutomationPeer.cs
- TreeViewImageIndexConverter.cs
- METAHEADER.cs
- CssStyleCollection.cs
- XmlObjectSerializer.cs
- DependencyPropertyHelper.cs
- SapiRecognizer.cs
- AdornerPresentationContext.cs
- DataRelation.cs
- DataExpression.cs
- WebUtil.cs
- TextParagraph.cs
- BinaryKeyIdentifierClause.cs
- DefaultTextStoreTextComposition.cs
- MessageEventSubscriptionService.cs
- InstallerTypeAttribute.cs
- PeerIPHelper.cs
- HwndSourceKeyboardInputSite.cs
- HttpHandlerAction.cs
- DataSourceSerializationException.cs
- DbConvert.cs
- WindowPattern.cs
- UIElement3D.cs
- ZipIOBlockManager.cs
- HotSpot.cs
- PropertyValueChangedEvent.cs
- Parser.cs
- RawMouseInputReport.cs
- CodeActivityContext.cs
- Utility.cs
- PeekCompletedEventArgs.cs
- CommandManager.cs
- querybuilder.cs
- CheckBoxStandardAdapter.cs
- TrackBarDesigner.cs
- TaskResultSetter.cs
- ObservableDictionary.cs
- ContentTextAutomationPeer.cs
- StorageMappingItemLoader.cs
- VerificationException.cs
- httpserverutility.cs
- DebugInfoGenerator.cs
- BitmapVisualManager.cs
- PrintEvent.cs
- SmiRecordBuffer.cs
- JoinSymbol.cs
- EditorPartChrome.cs
- AmbientLight.cs
- ModulesEntry.cs
- Utils.cs
- ProcessModuleCollection.cs
- OleDbConnection.cs
- HyperLinkStyle.cs
- BinHexDecoder.cs
- UIElementIsland.cs
- AggregateException.cs
- Dynamic.cs
- StaticExtensionConverter.cs
- TrackingQueryElement.cs
- PageVisual.cs
- FragmentQueryKB.cs
- IdleTimeoutMonitor.cs
- DataTableMappingCollection.cs
- Graphics.cs
- WebPartDescriptionCollection.cs
- XmlDesigner.cs
- MetadataPropertyAttribute.cs
- StatusBarAutomationPeer.cs
- XomlSerializationHelpers.cs
- QilParameter.cs
- ExpressionTextBoxAutomationPeer.cs
- GatewayDefinition.cs
- AppDomainProtocolHandler.cs
- CqlLexerHelpers.cs
- SmtpFailedRecipientsException.cs
- messageonlyhwndwrapper.cs
- MemberPathMap.cs
- MenuCommandsChangedEventArgs.cs
- CryptoKeySecurity.cs
- CacheDependency.cs
- SecureUICommand.cs
- HideDisabledControlAdapter.cs
- BitmapMetadataBlob.cs
- ClientCultureInfo.cs
- updateconfighost.cs
- NameValuePair.cs
- Preprocessor.cs
- GridView.cs
- PlaceHolder.cs
- ListBoxItemWrapperAutomationPeer.cs
- SqlServices.cs
- HTTPNotFoundHandler.cs