realtimenetprots/sipfw/SIP/Codec/src/SIPSyntaxCheck.cpp
changeset 0 307788aac0a8
child 26 822e1f077722
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Codec/src/SIPSyntaxCheck.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,850 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : SIPSyntaxCheck.cpp
+// Part of       : SIP Codec
+// Version       : SIP/4.0 
+//
+
+
+
+
+#include "SIPSyntaxCheck.h"
+#include "TSIPChar.h"
+#include "sipcodecerr.h"
+#include <uriutils.h>
+
+_LIT8(KSIP, "SIP");
+_LIT8(KTwoDots, "..");
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Token
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Token (const TDesC8& aValue)
+	{
+	if (aValue.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		if (!sipChr.IsTokenChar()) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::AlphaMaxSize8
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::AlphaMaxSize8 (const TDesC8& aValue)
+	{
+	if (aValue.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	TInt count = 1;
+	while (sipChr)
+		{
+		if (!sipChr.IsAlpha()) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		count++;
+		} 
+	return (count <= 9);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Host
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Host (const TDesC8& aValue)
+	{
+    if(aValue.Length() == 0)
+        {
+        return EFalse;
+        } 
+    CSIPHostPort::TType hostType;
+	return (SIPSyntaxCheck::HostType(aValue,hostType) == KErrNone);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Word
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Word (const TDesC8& aValue)
+	{
+	if (aValue.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		if (!sipChr.IsWordChar()) return EFalse;
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::User
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::User (const TDesC8& aUser)
+	{
+	if (aUser.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aUser);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		if (!(sipChr.IsUnreserved() || sipChr == '%' || sipChr == '&' ||
+			  sipChr == '=' || sipChr == '+' || sipChr == '$' ||
+			  sipChr == ',' || sipChr == ';' || sipChr == '?' ||
+			  sipChr == '/'))
+			{
+			return EFalse;
+			}
+		if (sipChr == '%' && !SkipAndCheckEscaped(lex)) // escaped
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Password
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Password (const TDesC8& aPassword)
+	{
+	if (aPassword.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aPassword);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		if (!(sipChr.IsUnreserved() || sipChr == '%' || sipChr == '&' ||
+			  sipChr == '=' || sipChr == '+' || sipChr == '$' ||
+			  sipChr == ','))
+			{
+			return EFalse;
+			}
+		if (sipChr == '%' && !SkipAndCheckEscaped(lex)) // escaped
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::StartsAndEndsWithQuotes
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::StartsAndEndsWithQuotes (const TDesC8& aValue)
+    {
+	// trim and check quotes
+	TLex8 lex(aValue);
+	lex.SkipSpace();
+	TPtrC8 trimmedVal(lex.Remainder());
+	const TInt KTwoQuotesLength = 2;
+	if (trimmedVal.Length() < KTwoQuotesLength) 
+		{
+		return EFalse;
+		}
+	if (trimmedVal.Locate('"') != 0) 
+		{
+		return EFalse;
+		}
+	if (trimmedVal.LocateReverse('"') != trimmedVal.Length()-1) 
+		{
+		return EFalse;
+		}
+	return ETrue;    
+    }
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::QuotedString
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::QuotedString (const TDesC8& aValue)
+	{
+	// trim and check quotes
+	TLex8 lex(aValue);
+	lex.SkipSpace();
+	TPtrC8 trimmedVal(lex.Remainder());
+	if (!StartsAndEndsWithQuotes(trimmedVal))
+	    {
+	    return EFalse;
+	    }
+	// remove quotes
+	TPtrC8 withoutFirstQuote(trimmedVal.Mid(1));
+	TPtrC8 withoutQuotes(withoutFirstQuote.Left(withoutFirstQuote.Length()-1));
+	// check value
+	return QuotedStringValue(withoutQuotes);
+	}
+	
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::QuotedStringValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::QuotedStringValue(
+    const TDesC8& aValue, 
+    const TChar& aExtraChr)
+	{
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		TBool ok = ETrue;
+		if (sipChr.IsUTF8NonAsciiStartChar())
+			{
+			ok = SkipAndCheckNonAscii(sipChr,lex);
+			}
+		else if (sipChr == '\\')
+			{
+			sipChr = lex.Get();
+			ok = sipChr.IsQuotedPairChar();
+			}
+		else if (sipChr.IsGdTextChar() || 
+		         sipChr == ' ' || 
+		         sipChr == '\t' ||
+		         sipChr == aExtraChr)
+			{
+			ok = ETrue;
+			}
+		else
+			{
+			ok = EFalse;
+			}
+		if (!ok) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}	
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::SIPVersion
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::SIPVersion (const TDesC8& aValue)
+	{
+	// "SIP" "/" 1*DIGIT "." 1*DIGIT
+	if (aValue.Length() < KSIP().Length()+4) 
+		{
+		return EFalse;
+		}
+	if (aValue.FindF(KSIP) != 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue.Mid(KSIP().Length()));
+	if (lex.Get() != '/') 
+		{
+		return EFalse;
+		}
+	TSIPChar sipChr = lex.Get();
+	if (!sipChr.IsDigit()) 
+		{
+		return EFalse;
+		}
+	while (sipChr.IsDigit()) 
+		{
+		sipChr = lex.Get();
+		}
+	if (sipChr != '.') 
+		{
+		return EFalse;
+		}
+	sipChr = lex.Get();
+	if (!sipChr.IsDigit()) 
+		{
+		return EFalse;
+		}
+	while (sipChr.IsDigit()) 
+		{
+		sipChr = lex.Get();
+		}
+	return (sipChr == 0);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::ReasonPhrase
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::ReasonPhrase (const TDesC8& aValue)
+	{
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		TBool ok = ETrue;
+		if (sipChr.IsUTF8NonAsciiStartChar())
+			{
+			ok = SkipAndCheckNonAscii(sipChr,lex);
+			}
+		else if (sipChr == '%') // escaped
+			{
+			ok = SkipAndCheckEscaped(lex);
+			}
+		else if (sipChr.IsReserved() || sipChr.IsUnreserved() || 
+			     sipChr.IsUTF8ContChar() || sipChr == ' ' || sipChr == '\t')
+			{
+			ok = ETrue;
+			}
+		else
+			{
+			ok = EFalse;
+			}
+		if (!ok) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::UInt
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::UInt (const TDesC8& aValue)
+	{
+	TUint tmp=0;
+	return UInt(aValue,tmp);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::UInt
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::UInt (const TDesC8& aValue, TUint& aResult)
+	{
+	if (aValue.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	TUint parsedValue=0;
+	if (lex.Val(parsedValue) != KErrNone) 
+		{
+		return EFalse;
+		}
+	if (lex.Remainder().Length() != 0) 
+		{
+		return EFalse;
+		}
+	aResult = parsedValue;
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Real
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Real (const TDesC8& aValue)
+	{
+	TReal tmp=0;
+	return Real(aValue,tmp);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Real
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Real (const TDesC8& aValue, TReal& aResult)
+	{
+	if (aValue.Length() == 0) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	TReal parsedValue=0;
+	// SIP uses always dot as a decimal point
+	const TChar KDotChr = '.';
+	if (lex.Val(parsedValue,KDotChr) != KErrNone) 
+		{
+		return EFalse;
+		}
+	if (lex.Remainder().Length() != 0) 
+		{
+		return EFalse;
+		}
+	aResult = parsedValue;
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::GenericParamValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::GenericParamValue (const TDesC8& aValue)
+	{
+	// token / host / quoted-string
+	if (Token(aValue)) 
+		{
+		return ETrue;
+		}
+	if (Host(aValue)) 
+		{
+		return ETrue;
+		}
+	return QuotedString(aValue);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::QValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::QValue (const TDesC8& aValue)
+	{
+	TReal q=0;
+	if (!Real(aValue,q)) 
+		{
+		return EFalse;
+		}
+	return (q >= 0 && q <= 1);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::TtlValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::TtlValue (const TDesC8& aValue)
+	{
+	const TUint KMaxTtlValue = 255;
+	TUint ttl=0;
+	if (!UInt(aValue,ttl)) 
+		{
+		return EFalse;
+		}
+	return (ttl <= KMaxTtlValue);
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::HexValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::HexValue (const TDesC8& aValue, TInt aLength)
+    {
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+    TInt count = 0;
+	while (sipChr.IsHexDigit())
+		{
+        count++;
+		sipChr = lex.Get();
+		}
+    if (aLength < 0) 
+        {
+        count = aLength;
+        }
+	return (count == aLength && sipChr == 0);
+    }
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::ExtensionHeaderValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::ExtensionHeaderValue (const TDesC8& aValue)
+	{
+	// CR or LF not allowed (line folds removed by pre-parser)
+	if (aValue.Length() == 0) 
+        {
+        return ETrue;
+        }
+	TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		TBool ok = ETrue;
+		if (sipChr.IsUTF8NonAsciiStartChar())
+			{
+			ok = SkipAndCheckNonAscii(sipChr,lex);
+			}
+		else if ((sipChr >= 33 && sipChr <= 126) || 
+			     sipChr.IsUTF8ContChar() || 
+			     sipChr == ' ' || 
+			     sipChr == '\t' ||
+			     sipChr == 2) // Used by Yahoo in authentication
+			{	
+			ok = ETrue;
+			}
+		else
+			{
+			ok = EFalse;
+			}
+		if (!ok) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::QuotedTokenWithComma
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::QuotedTokenWithComma (const TDesC8& aValue)
+    {
+	if (!aValue.Length()) 
+		{
+		return EFalse;
+		}
+	TLex8 lex(aValue);
+	lex.SkipSpace();
+	TSIPChar sipChr = lex.Get();
+	if(sipChr != '"') 
+		{
+		return EFalse;
+		}
+	sipChr = lex.Get();
+
+	while (sipChr.IsTokenChar() || sipChr == ',' || sipChr == ' ')
+		{
+		sipChr = lex.Get();
+		}
+	lex.UnGet();
+	sipChr = lex.Get();
+   	if (sipChr != '"')
+        {
+        return EFalse;
+        }
+	lex.SkipSpace();
+	return (lex.Get() == 0);
+    }	
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::HostType
+// -----------------------------------------------------------------------------
+//
+TInt SIPSyntaxCheck::HostType (const TDesC8& aHost, 
+                               CSIPHostPort::TType& aHostType)
+	{
+    if (aHost.Length() == 0)
+        {
+        return KErrSipCodecHost;
+        }
+    UriUtils::TUriHostType type = UriUtils::HostType(aHost);
+    if(type == UriUtils::ETextHost)
+	    {
+	    if(!ValidHostName(aHost))
+		    {
+		    aHostType = CSIPHostPort::ESIPNoHost;
+		    return KErrSipCodecHost;
+		    }
+	    aHostType = CSIPHostPort::ESIPHostName;
+	    }
+    else if(type == UriUtils::EIPv4Host)
+	    {
+	    aHostType = CSIPHostPort::ESIPIpv4;
+	    }
+    else // EIPv6Host
+	    {
+	    aHostType = CSIPHostPort::ESIPIpv6;
+	    }
+    return KErrNone;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Comment
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::Comment(const TDesC8& aComment)
+    {
+	// trim and check parenthesis
+	TLex8 lex(aComment);
+	lex.SkipSpace();
+	TPtrC8 trimmedVal(lex.Remainder());
+	if (trimmedVal.Length() < 2) 
+		{
+		return EFalse;
+		}
+	if (trimmedVal.Locate('(') != 0) 
+		{
+		return EFalse;
+		}
+	if (trimmedVal.LocateReverse(')') != trimmedVal.Length()-1) 
+		{
+		return EFalse;
+		}
+	// remove parenthesis
+	TPtrC8 withoutFirstParenthesis(trimmedVal.Mid(1));
+	TPtrC8 withoutParenthesis(withoutFirstParenthesis.Left(
+                              withoutFirstParenthesis.Length()-1));
+	lex.Assign(withoutParenthesis);
+	// check value without parenthesis
+	TSIPChar sipChr = lex.Get();
+	while (sipChr)
+		{
+		TBool ok = ETrue;
+		if (sipChr.IsUTF8NonAsciiStartChar())
+			{
+			ok = SkipAndCheckNonAscii(sipChr,lex);
+			}
+        else if ((sipChr >= 33 && sipChr <= 39) || 
+                (sipChr >= 42 && sipChr <= 91) || 
+                (sipChr >= 93 && sipChr <= 126))
+			{
+			ok = ETrue;
+			}
+		else if (sipChr == '\\')
+			{
+			sipChr = lex.Get();
+			ok = sipChr.IsQuotedPairChar();
+			}	
+        else if (sipChr.IsSpace() || sipChr == '(' || sipChr == ')')
+            {
+            ok = ETrue;
+            }
+		else
+			{
+			ok = EFalse;
+			}
+		if (!ok) 
+			{
+			return EFalse;
+			}
+		sipChr = lex.Get();
+		}
+	return ETrue;    
+    }
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::FeatureValue
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::FeatureValue(const TDesC8& aValue)
+    {
+	// trim and check quotes
+	TLex8 lex(aValue);
+	lex.SkipSpace();
+	TPtrC8 trimmedVal(lex.Remainder());
+	if (!StartsAndEndsWithQuotes(trimmedVal))
+	    {
+	    return EFalse;
+	    }
+	// remove quotes
+	TPtrC8 withoutFirstQuote(trimmedVal.Mid(1));
+	TPtrC8 withoutQuotes(withoutFirstQuote.Left(withoutFirstQuote.Length()-1));
+	lex.Assign(withoutQuotes);
+    // check value without quotes
+    TSIPChar sipChr = lex.Get();
+    while(sipChr)
+        {
+        TBool ok = ETrue;
+        if(sipChr.IsTokenChar())
+            {
+            ok = ETrue;
+            }
+		else if(sipChr.IsGdTextChar() || 
+                sipChr == '#' || 
+                sipChr == '=' || 
+                sipChr == ':')
+			{
+			ok = ETrue;
+			}
+		else
+			{
+			ok = EFalse;
+			}
+		if (!ok) 
+			{
+			return EFalse;
+			}
+        sipChr = lex.Get();
+        }
+
+    lex.SkipSpace();
+    return (lex.Get() == 0);
+    }
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::Base64Encoded
+// -----------------------------------------------------------------------------
+//    
+TBool SIPSyntaxCheck::Base64Encoded(const TDesC8& aValue)
+    {
+    TBool valid = ETrue;
+    TLex8 lex(aValue);
+	TSIPChar sipChr = lex.Get();
+	while (sipChr && valid)
+		{
+		if (sipChr.IsAlphaDigit() || 
+		    sipChr == '+' ||
+		    sipChr == '/' ||
+		    sipChr == '-' ||
+		    sipChr == '_' ||
+		    sipChr == '=')
+			{
+			sipChr = lex.Get();
+			}
+	    else
+	        {
+	        valid = EFalse;
+	        }
+		}
+    return valid;  
+    }
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::SkipAndCheckEscaped
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::SkipAndCheckEscaped (TLex8& aLex)
+	{
+	if (!aLex.Get().IsHexDigit()) 
+		{
+		return EFalse;
+		}
+	return (aLex.Get().IsHexDigit());
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::SkipAndCheckNonAscii
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::SkipAndCheckNonAscii (const TChar& aChr, TLex8& aLex)
+	{
+	if (aChr >= 192 && aChr <= 253)
+		{
+		if (aChr <= 223)
+			{
+			return SkipAndCheckContChars(aLex,1);
+			}
+		else if (aChr <= 239)
+			{
+			return SkipAndCheckContChars(aLex,2);
+			}
+		else if (aChr <= 247)
+			{
+			return SkipAndCheckContChars(aLex,3);
+			}
+		else if (aChr <= 251)
+			{
+			return SkipAndCheckContChars(aLex,4);
+			}
+		else
+			{
+			return SkipAndCheckContChars(aLex,5);
+			}
+		}
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::SkipAndCheckContChars
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::SkipAndCheckContChars (TLex8& aLex, TInt aCount)
+	{
+	TInt counter = 0;
+	TSIPChar chr = 0;
+	while (aCount > counter++)
+		{
+		chr = aLex.Get();
+		if (!chr.IsUTF8ContChar())
+			{
+			return EFalse;
+			}
+		}
+	return ETrue;
+	}
+    
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::ValidHostName
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::ValidHostName(const TDesC8& aHost)
+	{
+	if (aHost.Length() == 0 || aHost.Find(KTwoDots) >= 0) 
+	    {
+	    return EFalse;
+	    }
+	TLex8 hostLex(aHost);
+	TPtrC8 label;
+	if (!NextHostLabelOk(hostLex,label))
+	    {
+	    return EFalse;
+	    }
+	TPtrC8 lastLabel;
+	while (label.Length() > 0)
+		{
+		lastLabel.Set (label);
+		if (!NextHostLabelOk(hostLex,label))
+		    {
+		    return EFalse;
+		    }
+		}
+	TLex8 lastLabelLex(lastLabel);
+	return (lastLabelLex.Peek().IsAlpha());
+	}
+
+// -----------------------------------------------------------------------------
+// SIPSyntaxCheck::NextHostLabelOk
+// -----------------------------------------------------------------------------
+//
+TBool SIPSyntaxCheck::NextHostLabelOk(TLex8& aLex, TPtrC8& aLabel)
+	{
+	TUint chrCount=0;
+	aLex.Mark();
+	TChar chr = aLex.Get();
+	if (chr == '-') 
+	    {
+	    return EFalse;
+	    }
+	TChar lastChr = chr;
+	while (chr != 0 && chr != '.')
+		{
+		if (!(chr.IsAlphaDigit() || chr == '-'))
+		    {
+		    return EFalse;
+		    }
+		chrCount++;
+		lastChr = chr;
+		chr = aLex.Get();
+		}
+	if (lastChr == '-')
+	    {
+	    return EFalse;
+	    }
+	aLabel.Set(aLex.RemainderFromMark().Left(chrCount));
+	return ETrue;
+	}