realtimenetprots/sipfw/SIP/Codec/src/SIPSyntaxCheck.cpp
changeset 0 307788aac0a8
child 26 822e1f077722
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : SIPSyntaxCheck.cpp
       
    15 // Part of       : SIP Codec
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "SIPSyntaxCheck.h"
       
    23 #include "TSIPChar.h"
       
    24 #include "sipcodecerr.h"
       
    25 #include <uriutils.h>
       
    26 
       
    27 _LIT8(KSIP, "SIP");
       
    28 _LIT8(KTwoDots, "..");
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // SIPSyntaxCheck::Token
       
    32 // -----------------------------------------------------------------------------
       
    33 //
       
    34 TBool SIPSyntaxCheck::Token (const TDesC8& aValue)
       
    35 	{
       
    36 	if (aValue.Length() == 0) 
       
    37 		{
       
    38 		return EFalse;
       
    39 		}
       
    40 	TLex8 lex(aValue);
       
    41 	TSIPChar sipChr = lex.Get();
       
    42 	while (sipChr)
       
    43 		{
       
    44 		if (!sipChr.IsTokenChar()) 
       
    45 			{
       
    46 			return EFalse;
       
    47 			}
       
    48 		sipChr = lex.Get();
       
    49 		}
       
    50 	return ETrue;
       
    51 	}
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // SIPSyntaxCheck::AlphaMaxSize8
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 TBool SIPSyntaxCheck::AlphaMaxSize8 (const TDesC8& aValue)
       
    58 	{
       
    59 	if (aValue.Length() == 0) 
       
    60 		{
       
    61 		return EFalse;
       
    62 		}
       
    63 	TLex8 lex(aValue);
       
    64 	TSIPChar sipChr = lex.Get();
       
    65 	TInt count = 1;
       
    66 	while (sipChr)
       
    67 		{
       
    68 		if (!sipChr.IsAlpha()) 
       
    69 			{
       
    70 			return EFalse;
       
    71 			}
       
    72 		sipChr = lex.Get();
       
    73 		count++;
       
    74 		} 
       
    75 	return (count <= 9);
       
    76 	}
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // SIPSyntaxCheck::Host
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 TBool SIPSyntaxCheck::Host (const TDesC8& aValue)
       
    83 	{
       
    84     if(aValue.Length() == 0)
       
    85         {
       
    86         return EFalse;
       
    87         } 
       
    88     CSIPHostPort::TType hostType;
       
    89 	return (SIPSyntaxCheck::HostType(aValue,hostType) == KErrNone);
       
    90 	}
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // SIPSyntaxCheck::Word
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 TBool SIPSyntaxCheck::Word (const TDesC8& aValue)
       
    97 	{
       
    98 	if (aValue.Length() == 0) 
       
    99 		{
       
   100 		return EFalse;
       
   101 		}
       
   102 	TLex8 lex(aValue);
       
   103 	TSIPChar sipChr = lex.Get();
       
   104 	while (sipChr)
       
   105 		{
       
   106 		if (!sipChr.IsWordChar()) return EFalse;
       
   107 		sipChr = lex.Get();
       
   108 		}
       
   109 	return ETrue;
       
   110 	}
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // SIPSyntaxCheck::User
       
   114 // -----------------------------------------------------------------------------
       
   115 //
       
   116 TBool SIPSyntaxCheck::User (const TDesC8& aUser)
       
   117 	{
       
   118 	if (aUser.Length() == 0) 
       
   119 		{
       
   120 		return EFalse;
       
   121 		}
       
   122 	TLex8 lex(aUser);
       
   123 	TSIPChar sipChr = lex.Get();
       
   124 	while (sipChr)
       
   125 		{
       
   126 		if (!(sipChr.IsUnreserved() || sipChr == '%' || sipChr == '&' ||
       
   127 			  sipChr == '=' || sipChr == '+' || sipChr == '$' ||
       
   128 			  sipChr == ',' || sipChr == ';' || sipChr == '?' ||
       
   129 			  sipChr == '/'))
       
   130 			{
       
   131 			return EFalse;
       
   132 			}
       
   133 		if (sipChr == '%' && !SkipAndCheckEscaped(lex)) // escaped
       
   134 			{
       
   135 			return EFalse;
       
   136 			}
       
   137 		sipChr = lex.Get();
       
   138 		}
       
   139 	return ETrue;
       
   140 	}
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // SIPSyntaxCheck::Password
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 TBool SIPSyntaxCheck::Password (const TDesC8& aPassword)
       
   147 	{
       
   148 	if (aPassword.Length() == 0) 
       
   149 		{
       
   150 		return EFalse;
       
   151 		}
       
   152 	TLex8 lex(aPassword);
       
   153 	TSIPChar sipChr = lex.Get();
       
   154 	while (sipChr)
       
   155 		{
       
   156 		if (!(sipChr.IsUnreserved() || sipChr == '%' || sipChr == '&' ||
       
   157 			  sipChr == '=' || sipChr == '+' || sipChr == '$' ||
       
   158 			  sipChr == ','))
       
   159 			{
       
   160 			return EFalse;
       
   161 			}
       
   162 		if (sipChr == '%' && !SkipAndCheckEscaped(lex)) // escaped
       
   163 			{
       
   164 			return EFalse;
       
   165 			}
       
   166 		sipChr = lex.Get();
       
   167 		}
       
   168 	return ETrue;
       
   169 	}
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 // SIPSyntaxCheck::StartsAndEndsWithQuotes
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 TBool SIPSyntaxCheck::StartsAndEndsWithQuotes (const TDesC8& aValue)
       
   176     {
       
   177 	// trim and check quotes
       
   178 	TLex8 lex(aValue);
       
   179 	lex.SkipSpace();
       
   180 	TPtrC8 trimmedVal(lex.Remainder());
       
   181 	const TInt KTwoQuotesLength = 2;
       
   182 	if (trimmedVal.Length() < KTwoQuotesLength) 
       
   183 		{
       
   184 		return EFalse;
       
   185 		}
       
   186 	if (trimmedVal.Locate('"') != 0) 
       
   187 		{
       
   188 		return EFalse;
       
   189 		}
       
   190 	if (trimmedVal.LocateReverse('"') != trimmedVal.Length()-1) 
       
   191 		{
       
   192 		return EFalse;
       
   193 		}
       
   194 	return ETrue;    
       
   195     }
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // SIPSyntaxCheck::QuotedString
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 TBool SIPSyntaxCheck::QuotedString (const TDesC8& aValue)
       
   202 	{
       
   203 	// trim and check quotes
       
   204 	TLex8 lex(aValue);
       
   205 	lex.SkipSpace();
       
   206 	TPtrC8 trimmedVal(lex.Remainder());
       
   207 	if (!StartsAndEndsWithQuotes(trimmedVal))
       
   208 	    {
       
   209 	    return EFalse;
       
   210 	    }
       
   211 	// remove quotes
       
   212 	TPtrC8 withoutFirstQuote(trimmedVal.Mid(1));
       
   213 	TPtrC8 withoutQuotes(withoutFirstQuote.Left(withoutFirstQuote.Length()-1));
       
   214 	// check value
       
   215 	return QuotedStringValue(withoutQuotes);
       
   216 	}
       
   217 	
       
   218 // -----------------------------------------------------------------------------
       
   219 // SIPSyntaxCheck::QuotedStringValue
       
   220 // -----------------------------------------------------------------------------
       
   221 //
       
   222 TBool SIPSyntaxCheck::QuotedStringValue(
       
   223     const TDesC8& aValue, 
       
   224     const TChar& aExtraChr)
       
   225 	{
       
   226 	TLex8 lex(aValue);
       
   227 	TSIPChar sipChr = lex.Get();
       
   228 	while (sipChr)
       
   229 		{
       
   230 		TBool ok = ETrue;
       
   231 		if (sipChr.IsUTF8NonAsciiStartChar())
       
   232 			{
       
   233 			ok = SkipAndCheckNonAscii(sipChr,lex);
       
   234 			}
       
   235 		else if (sipChr == '\\')
       
   236 			{
       
   237 			sipChr = lex.Get();
       
   238 			ok = sipChr.IsQuotedPairChar();
       
   239 			}
       
   240 		else if (sipChr.IsGdTextChar() || 
       
   241 		         sipChr == ' ' || 
       
   242 		         sipChr == '\t' ||
       
   243 		         sipChr == aExtraChr)
       
   244 			{
       
   245 			ok = ETrue;
       
   246 			}
       
   247 		else
       
   248 			{
       
   249 			ok = EFalse;
       
   250 			}
       
   251 		if (!ok) 
       
   252 			{
       
   253 			return EFalse;
       
   254 			}
       
   255 		sipChr = lex.Get();
       
   256 		}
       
   257 	return ETrue;
       
   258 	}	
       
   259 
       
   260 // -----------------------------------------------------------------------------
       
   261 // SIPSyntaxCheck::SIPVersion
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 TBool SIPSyntaxCheck::SIPVersion (const TDesC8& aValue)
       
   265 	{
       
   266 	// "SIP" "/" 1*DIGIT "." 1*DIGIT
       
   267 	if (aValue.Length() < KSIP().Length()+4) 
       
   268 		{
       
   269 		return EFalse;
       
   270 		}
       
   271 	if (aValue.FindF(KSIP) != 0) 
       
   272 		{
       
   273 		return EFalse;
       
   274 		}
       
   275 	TLex8 lex(aValue.Mid(KSIP().Length()));
       
   276 	if (lex.Get() != '/') 
       
   277 		{
       
   278 		return EFalse;
       
   279 		}
       
   280 	TSIPChar sipChr = lex.Get();
       
   281 	if (!sipChr.IsDigit()) 
       
   282 		{
       
   283 		return EFalse;
       
   284 		}
       
   285 	while (sipChr.IsDigit()) 
       
   286 		{
       
   287 		sipChr = lex.Get();
       
   288 		}
       
   289 	if (sipChr != '.') 
       
   290 		{
       
   291 		return EFalse;
       
   292 		}
       
   293 	sipChr = lex.Get();
       
   294 	if (!sipChr.IsDigit()) 
       
   295 		{
       
   296 		return EFalse;
       
   297 		}
       
   298 	while (sipChr.IsDigit()) 
       
   299 		{
       
   300 		sipChr = lex.Get();
       
   301 		}
       
   302 	return (sipChr == 0);
       
   303 	}
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // SIPSyntaxCheck::ReasonPhrase
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 TBool SIPSyntaxCheck::ReasonPhrase (const TDesC8& aValue)
       
   310 	{
       
   311 	TLex8 lex(aValue);
       
   312 	TSIPChar sipChr = lex.Get();
       
   313 	while (sipChr)
       
   314 		{
       
   315 		TBool ok = ETrue;
       
   316 		if (sipChr.IsUTF8NonAsciiStartChar())
       
   317 			{
       
   318 			ok = SkipAndCheckNonAscii(sipChr,lex);
       
   319 			}
       
   320 		else if (sipChr == '%') // escaped
       
   321 			{
       
   322 			ok = SkipAndCheckEscaped(lex);
       
   323 			}
       
   324 		else if (sipChr.IsReserved() || sipChr.IsUnreserved() || 
       
   325 			     sipChr.IsUTF8ContChar() || sipChr == ' ' || sipChr == '\t')
       
   326 			{
       
   327 			ok = ETrue;
       
   328 			}
       
   329 		else
       
   330 			{
       
   331 			ok = EFalse;
       
   332 			}
       
   333 		if (!ok) 
       
   334 			{
       
   335 			return EFalse;
       
   336 			}
       
   337 		sipChr = lex.Get();
       
   338 		}
       
   339 	return ETrue;
       
   340 	}
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // SIPSyntaxCheck::UInt
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 TBool SIPSyntaxCheck::UInt (const TDesC8& aValue)
       
   347 	{
       
   348 	TUint tmp=0;
       
   349 	return UInt(aValue,tmp);
       
   350 	}
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // SIPSyntaxCheck::UInt
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 TBool SIPSyntaxCheck::UInt (const TDesC8& aValue, TUint& aResult)
       
   357 	{
       
   358 	if (aValue.Length() == 0) 
       
   359 		{
       
   360 		return EFalse;
       
   361 		}
       
   362 	TLex8 lex(aValue);
       
   363 	TUint parsedValue=0;
       
   364 	if (lex.Val(parsedValue) != KErrNone) 
       
   365 		{
       
   366 		return EFalse;
       
   367 		}
       
   368 	if (lex.Remainder().Length() != 0) 
       
   369 		{
       
   370 		return EFalse;
       
   371 		}
       
   372 	aResult = parsedValue;
       
   373 	return ETrue;
       
   374 	}
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // SIPSyntaxCheck::Real
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 TBool SIPSyntaxCheck::Real (const TDesC8& aValue)
       
   381 	{
       
   382 	TReal tmp=0;
       
   383 	return Real(aValue,tmp);
       
   384 	}
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // SIPSyntaxCheck::Real
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 TBool SIPSyntaxCheck::Real (const TDesC8& aValue, TReal& aResult)
       
   391 	{
       
   392 	if (aValue.Length() == 0) 
       
   393 		{
       
   394 		return EFalse;
       
   395 		}
       
   396 	TLex8 lex(aValue);
       
   397 	TReal parsedValue=0;
       
   398 	// SIP uses always dot as a decimal point
       
   399 	const TChar KDotChr = '.';
       
   400 	if (lex.Val(parsedValue,KDotChr) != KErrNone) 
       
   401 		{
       
   402 		return EFalse;
       
   403 		}
       
   404 	if (lex.Remainder().Length() != 0) 
       
   405 		{
       
   406 		return EFalse;
       
   407 		}
       
   408 	aResult = parsedValue;
       
   409 	return ETrue;
       
   410 	}
       
   411 
       
   412 // -----------------------------------------------------------------------------
       
   413 // SIPSyntaxCheck::GenericParamValue
       
   414 // -----------------------------------------------------------------------------
       
   415 //
       
   416 TBool SIPSyntaxCheck::GenericParamValue (const TDesC8& aValue)
       
   417 	{
       
   418 	// token / host / quoted-string
       
   419 	if (Token(aValue)) 
       
   420 		{
       
   421 		return ETrue;
       
   422 		}
       
   423 	if (Host(aValue)) 
       
   424 		{
       
   425 		return ETrue;
       
   426 		}
       
   427 	return QuotedString(aValue);
       
   428 	}
       
   429 
       
   430 // -----------------------------------------------------------------------------
       
   431 // SIPSyntaxCheck::QValue
       
   432 // -----------------------------------------------------------------------------
       
   433 //
       
   434 TBool SIPSyntaxCheck::QValue (const TDesC8& aValue)
       
   435 	{
       
   436 	TReal q=0;
       
   437 	if (!Real(aValue,q)) 
       
   438 		{
       
   439 		return EFalse;
       
   440 		}
       
   441 	return (q >= 0 && q <= 1);
       
   442 	}
       
   443 
       
   444 // -----------------------------------------------------------------------------
       
   445 // SIPSyntaxCheck::TtlValue
       
   446 // -----------------------------------------------------------------------------
       
   447 //
       
   448 TBool SIPSyntaxCheck::TtlValue (const TDesC8& aValue)
       
   449 	{
       
   450 	const TUint KMaxTtlValue = 255;
       
   451 	TUint ttl=0;
       
   452 	if (!UInt(aValue,ttl)) 
       
   453 		{
       
   454 		return EFalse;
       
   455 		}
       
   456 	return (ttl <= KMaxTtlValue);
       
   457 	}
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // SIPSyntaxCheck::HexValue
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 TBool SIPSyntaxCheck::HexValue (const TDesC8& aValue, TInt aLength)
       
   464     {
       
   465 	TLex8 lex(aValue);
       
   466 	TSIPChar sipChr = lex.Get();
       
   467     TInt count = 0;
       
   468 	while (sipChr.IsHexDigit())
       
   469 		{
       
   470         count++;
       
   471 		sipChr = lex.Get();
       
   472 		}
       
   473     if (aLength < 0) 
       
   474         {
       
   475         count = aLength;
       
   476         }
       
   477 	return (count == aLength && sipChr == 0);
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // SIPSyntaxCheck::ExtensionHeaderValue
       
   482 // -----------------------------------------------------------------------------
       
   483 //
       
   484 TBool SIPSyntaxCheck::ExtensionHeaderValue (const TDesC8& aValue)
       
   485 	{
       
   486 	// CR or LF not allowed (line folds removed by pre-parser)
       
   487 	if (aValue.Length() == 0) 
       
   488         {
       
   489         return ETrue;
       
   490         }
       
   491 	TLex8 lex(aValue);
       
   492 	TSIPChar sipChr = lex.Get();
       
   493 	while (sipChr)
       
   494 		{
       
   495 		TBool ok = ETrue;
       
   496 		if (sipChr.IsUTF8NonAsciiStartChar())
       
   497 			{
       
   498 			ok = SkipAndCheckNonAscii(sipChr,lex);
       
   499 			}
       
   500 		else if ((sipChr >= 33 && sipChr <= 126) || 
       
   501 			     sipChr.IsUTF8ContChar() || 
       
   502 			     sipChr == ' ' || 
       
   503 			     sipChr == '\t' ||
       
   504 			     sipChr == 2) // Used by Yahoo in authentication
       
   505 			{	
       
   506 			ok = ETrue;
       
   507 			}
       
   508 		else
       
   509 			{
       
   510 			ok = EFalse;
       
   511 			}
       
   512 		if (!ok) 
       
   513 			{
       
   514 			return EFalse;
       
   515 			}
       
   516 		sipChr = lex.Get();
       
   517 		}
       
   518 	return ETrue;
       
   519 	}
       
   520 
       
   521 // -----------------------------------------------------------------------------
       
   522 // SIPSyntaxCheck::QuotedTokenWithComma
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 TBool SIPSyntaxCheck::QuotedTokenWithComma (const TDesC8& aValue)
       
   526     {
       
   527 	if (!aValue.Length()) 
       
   528 		{
       
   529 		return EFalse;
       
   530 		}
       
   531 	TLex8 lex(aValue);
       
   532 	lex.SkipSpace();
       
   533 	TSIPChar sipChr = lex.Get();
       
   534 	if(sipChr != '"') 
       
   535 		{
       
   536 		return EFalse;
       
   537 		}
       
   538 	sipChr = lex.Get();
       
   539 
       
   540 	while (sipChr.IsTokenChar() || sipChr == ',' || sipChr == ' ')
       
   541 		{
       
   542 		sipChr = lex.Get();
       
   543 		}
       
   544 	lex.UnGet();
       
   545 	sipChr = lex.Get();
       
   546    	if (sipChr != '"')
       
   547         {
       
   548         return EFalse;
       
   549         }
       
   550 	lex.SkipSpace();
       
   551 	return (lex.Get() == 0);
       
   552     }	
       
   553 
       
   554 // -----------------------------------------------------------------------------
       
   555 // SIPSyntaxCheck::HostType
       
   556 // -----------------------------------------------------------------------------
       
   557 //
       
   558 TInt SIPSyntaxCheck::HostType (const TDesC8& aHost, 
       
   559                                CSIPHostPort::TType& aHostType)
       
   560 	{
       
   561     if (aHost.Length() == 0)
       
   562         {
       
   563         return KErrSipCodecHost;
       
   564         }
       
   565     UriUtils::TUriHostType type = UriUtils::HostType(aHost);
       
   566     if(type == UriUtils::ETextHost)
       
   567 	    {
       
   568 	    if(!ValidHostName(aHost))
       
   569 		    {
       
   570 		    aHostType = CSIPHostPort::ESIPNoHost;
       
   571 		    return KErrSipCodecHost;
       
   572 		    }
       
   573 	    aHostType = CSIPHostPort::ESIPHostName;
       
   574 	    }
       
   575     else if(type == UriUtils::EIPv4Host)
       
   576 	    {
       
   577 	    aHostType = CSIPHostPort::ESIPIpv4;
       
   578 	    }
       
   579     else // EIPv6Host
       
   580 	    {
       
   581 	    aHostType = CSIPHostPort::ESIPIpv6;
       
   582 	    }
       
   583     return KErrNone;
       
   584 	}
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // SIPSyntaxCheck::Comment
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 TBool SIPSyntaxCheck::Comment(const TDesC8& aComment)
       
   591     {
       
   592 	// trim and check parenthesis
       
   593 	TLex8 lex(aComment);
       
   594 	lex.SkipSpace();
       
   595 	TPtrC8 trimmedVal(lex.Remainder());
       
   596 	if (trimmedVal.Length() < 2) 
       
   597 		{
       
   598 		return EFalse;
       
   599 		}
       
   600 	if (trimmedVal.Locate('(') != 0) 
       
   601 		{
       
   602 		return EFalse;
       
   603 		}
       
   604 	if (trimmedVal.LocateReverse(')') != trimmedVal.Length()-1) 
       
   605 		{
       
   606 		return EFalse;
       
   607 		}
       
   608 	// remove parenthesis
       
   609 	TPtrC8 withoutFirstParenthesis(trimmedVal.Mid(1));
       
   610 	TPtrC8 withoutParenthesis(withoutFirstParenthesis.Left(
       
   611                               withoutFirstParenthesis.Length()-1));
       
   612 	lex.Assign(withoutParenthesis);
       
   613 	// check value without parenthesis
       
   614 	TSIPChar sipChr = lex.Get();
       
   615 	while (sipChr)
       
   616 		{
       
   617 		TBool ok = ETrue;
       
   618 		if (sipChr.IsUTF8NonAsciiStartChar())
       
   619 			{
       
   620 			ok = SkipAndCheckNonAscii(sipChr,lex);
       
   621 			}
       
   622         else if ((sipChr >= 33 && sipChr <= 39) || 
       
   623                 (sipChr >= 42 && sipChr <= 91) || 
       
   624                 (sipChr >= 93 && sipChr <= 126))
       
   625 			{
       
   626 			ok = ETrue;
       
   627 			}
       
   628 		else if (sipChr == '\\')
       
   629 			{
       
   630 			sipChr = lex.Get();
       
   631 			ok = sipChr.IsQuotedPairChar();
       
   632 			}	
       
   633         else if (sipChr.IsSpace() || sipChr == '(' || sipChr == ')')
       
   634             {
       
   635             ok = ETrue;
       
   636             }
       
   637 		else
       
   638 			{
       
   639 			ok = EFalse;
       
   640 			}
       
   641 		if (!ok) 
       
   642 			{
       
   643 			return EFalse;
       
   644 			}
       
   645 		sipChr = lex.Get();
       
   646 		}
       
   647 	return ETrue;    
       
   648     }
       
   649 
       
   650 // -----------------------------------------------------------------------------
       
   651 // SIPSyntaxCheck::FeatureValue
       
   652 // -----------------------------------------------------------------------------
       
   653 //
       
   654 TBool SIPSyntaxCheck::FeatureValue(const TDesC8& aValue)
       
   655     {
       
   656 	// trim and check quotes
       
   657 	TLex8 lex(aValue);
       
   658 	lex.SkipSpace();
       
   659 	TPtrC8 trimmedVal(lex.Remainder());
       
   660 	if (!StartsAndEndsWithQuotes(trimmedVal))
       
   661 	    {
       
   662 	    return EFalse;
       
   663 	    }
       
   664 	// remove quotes
       
   665 	TPtrC8 withoutFirstQuote(trimmedVal.Mid(1));
       
   666 	TPtrC8 withoutQuotes(withoutFirstQuote.Left(withoutFirstQuote.Length()-1));
       
   667 	lex.Assign(withoutQuotes);
       
   668     // check value without quotes
       
   669     TSIPChar sipChr = lex.Get();
       
   670     while(sipChr)
       
   671         {
       
   672         TBool ok = ETrue;
       
   673         if(sipChr.IsTokenChar())
       
   674             {
       
   675             ok = ETrue;
       
   676             }
       
   677 		else if(sipChr.IsGdTextChar() || 
       
   678                 sipChr == '#' || 
       
   679                 sipChr == '=' || 
       
   680                 sipChr == ':')
       
   681 			{
       
   682 			ok = ETrue;
       
   683 			}
       
   684 		else
       
   685 			{
       
   686 			ok = EFalse;
       
   687 			}
       
   688 		if (!ok) 
       
   689 			{
       
   690 			return EFalse;
       
   691 			}
       
   692         sipChr = lex.Get();
       
   693         }
       
   694 
       
   695     lex.SkipSpace();
       
   696     return (lex.Get() == 0);
       
   697     }
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // SIPSyntaxCheck::Base64Encoded
       
   701 // -----------------------------------------------------------------------------
       
   702 //    
       
   703 TBool SIPSyntaxCheck::Base64Encoded(const TDesC8& aValue)
       
   704     {
       
   705     TBool valid = ETrue;
       
   706     TLex8 lex(aValue);
       
   707 	TSIPChar sipChr = lex.Get();
       
   708 	while (sipChr && valid)
       
   709 		{
       
   710 		if (sipChr.IsAlphaDigit() || 
       
   711 		    sipChr == '+' ||
       
   712 		    sipChr == '/' ||
       
   713 		    sipChr == '-' ||
       
   714 		    sipChr == '_' ||
       
   715 		    sipChr == '=')
       
   716 			{
       
   717 			sipChr = lex.Get();
       
   718 			}
       
   719 	    else
       
   720 	        {
       
   721 	        valid = EFalse;
       
   722 	        }
       
   723 		}
       
   724     return valid;  
       
   725     }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // SIPSyntaxCheck::SkipAndCheckEscaped
       
   729 // -----------------------------------------------------------------------------
       
   730 //
       
   731 TBool SIPSyntaxCheck::SkipAndCheckEscaped (TLex8& aLex)
       
   732 	{
       
   733 	if (!aLex.Get().IsHexDigit()) 
       
   734 		{
       
   735 		return EFalse;
       
   736 		}
       
   737 	return (aLex.Get().IsHexDigit());
       
   738 	}
       
   739 
       
   740 // -----------------------------------------------------------------------------
       
   741 // SIPSyntaxCheck::SkipAndCheckNonAscii
       
   742 // -----------------------------------------------------------------------------
       
   743 //
       
   744 TBool SIPSyntaxCheck::SkipAndCheckNonAscii (const TChar& aChr, TLex8& aLex)
       
   745 	{
       
   746 	if (aChr >= 192 && aChr <= 253)
       
   747 		{
       
   748 		if (aChr <= 223)
       
   749 			{
       
   750 			return SkipAndCheckContChars(aLex,1);
       
   751 			}
       
   752 		else if (aChr <= 239)
       
   753 			{
       
   754 			return SkipAndCheckContChars(aLex,2);
       
   755 			}
       
   756 		else if (aChr <= 247)
       
   757 			{
       
   758 			return SkipAndCheckContChars(aLex,3);
       
   759 			}
       
   760 		else if (aChr <= 251)
       
   761 			{
       
   762 			return SkipAndCheckContChars(aLex,4);
       
   763 			}
       
   764 		else
       
   765 			{
       
   766 			return SkipAndCheckContChars(aLex,5);
       
   767 			}
       
   768 		}
       
   769 	return EFalse;
       
   770 	}
       
   771 
       
   772 // -----------------------------------------------------------------------------
       
   773 // SIPSyntaxCheck::SkipAndCheckContChars
       
   774 // -----------------------------------------------------------------------------
       
   775 //
       
   776 TBool SIPSyntaxCheck::SkipAndCheckContChars (TLex8& aLex, TInt aCount)
       
   777 	{
       
   778 	TInt counter = 0;
       
   779 	TSIPChar chr = 0;
       
   780 	while (aCount > counter++)
       
   781 		{
       
   782 		chr = aLex.Get();
       
   783 		if (!chr.IsUTF8ContChar())
       
   784 			{
       
   785 			return EFalse;
       
   786 			}
       
   787 		}
       
   788 	return ETrue;
       
   789 	}
       
   790     
       
   791 // -----------------------------------------------------------------------------
       
   792 // SIPSyntaxCheck::ValidHostName
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 TBool SIPSyntaxCheck::ValidHostName(const TDesC8& aHost)
       
   796 	{
       
   797 	if (aHost.Length() == 0 || aHost.Find(KTwoDots) >= 0) 
       
   798 	    {
       
   799 	    return EFalse;
       
   800 	    }
       
   801 	TLex8 hostLex(aHost);
       
   802 	TPtrC8 label;
       
   803 	if (!NextHostLabelOk(hostLex,label))
       
   804 	    {
       
   805 	    return EFalse;
       
   806 	    }
       
   807 	TPtrC8 lastLabel;
       
   808 	while (label.Length() > 0)
       
   809 		{
       
   810 		lastLabel.Set (label);
       
   811 		if (!NextHostLabelOk(hostLex,label))
       
   812 		    {
       
   813 		    return EFalse;
       
   814 		    }
       
   815 		}
       
   816 	TLex8 lastLabelLex(lastLabel);
       
   817 	return (lastLabelLex.Peek().IsAlpha());
       
   818 	}
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // SIPSyntaxCheck::NextHostLabelOk
       
   822 // -----------------------------------------------------------------------------
       
   823 //
       
   824 TBool SIPSyntaxCheck::NextHostLabelOk(TLex8& aLex, TPtrC8& aLabel)
       
   825 	{
       
   826 	TUint chrCount=0;
       
   827 	aLex.Mark();
       
   828 	TChar chr = aLex.Get();
       
   829 	if (chr == '-') 
       
   830 	    {
       
   831 	    return EFalse;
       
   832 	    }
       
   833 	TChar lastChr = chr;
       
   834 	while (chr != 0 && chr != '.')
       
   835 		{
       
   836 		if (!(chr.IsAlphaDigit() || chr == '-'))
       
   837 		    {
       
   838 		    return EFalse;
       
   839 		    }
       
   840 		chrCount++;
       
   841 		lastChr = chr;
       
   842 		chr = aLex.Get();
       
   843 		}
       
   844 	if (lastChr == '-')
       
   845 	    {
       
   846 	    return EFalse;
       
   847 	    }
       
   848 	aLabel.Set(aLex.RemainderFromMark().Left(chrCount));
       
   849 	return ETrue;
       
   850 	}