os/ossrv/genericservices/httputils/UriParser/TValidator.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericservices/httputils/UriParser/TValidator.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,799 @@
     1.4 +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +// System includes
    1.20 +#include <uriutilscommon.h>
    1.21 +#include <uriutils.h>
    1.22 +#include <delimitedpathsegment8.h>
    1.23 +#include <delimitedquery8.h>
    1.24 +#include <escapeutils.h>
    1.25 +
    1.26 +//User includes
    1.27 +#include "UriUtilsInternal.h"
    1.28 +#include "TValidator.h"
    1.29 +
    1.30 +//Constants
    1.31 +_LIT8(KTransport, "transport");
    1.32 +_LIT8(KUser, "user"); 
    1.33 +_LIT8(KMethod, "method");
    1.34 +_LIT8(KTtl, "ttl");
    1.35 +_LIT8(KMaddr, "maddr");
    1.36 +_LIT8(KLr, "lr");
    1.37 +_LIT8(KExtension, "ext" );
    1.38 +_LIT8(KIsdnSubAddress, "isub" );
    1.39 +_LIT8(KContext, "phone-context" );
    1.40 +const TInt KMaxHostAddr = 255;
    1.41 +
    1.42 +
    1.43 +/**
    1.44 +	Constructor.
    1.45 + */
    1.46 +TValidatorBase::TValidatorBase(const TUriC8& aUri)
    1.47 +: iUri(aUri)
    1.48 +	{
    1.49 +	}
    1.50 +
    1.51 +/**
    1.52 +	Checks the Uri to be valid. 
    1.53 +	If there is no valid Host, Port, userinfo, Path, Query or Fragment then the 
    1.54 +	return value indicates an appropriate invalid Component. else returns zero, 
    1.55 +	which indicates given uri is valid.
    1.56 +
    1.57 +	@return whether the Uri is Valid by returning zero or appropriate error value 
    1.58 +			for Invalid Uri.
    1.59 + */
    1.60 +TInt TValidatorBase::Validate()
    1.61 +	{
    1.62 +	if (!IsValidHost())
    1.63 +		{
    1.64 +		return KUriUtilsErrInvalidHost;
    1.65 +		}
    1.66 +	
    1.67 +	if (!IsValidPort())
    1.68 +		{
    1.69 +		return KUriUtilsErrInvalidPort;
    1.70 +		}
    1.71 +		
    1.72 +	if (!IsValidUserInfo())
    1.73 +		{
    1.74 +		return KUriUtilsErrInvalidUserInfo;
    1.75 +		}
    1.76 +	
    1.77 +	if (!IsValidPath())
    1.78 +		{
    1.79 +		return KUriUtilsErrInvalidParam;
    1.80 +		}
    1.81 +	
    1.82 +	if (!IsValidQuery())
    1.83 +		{
    1.84 +		return KUriUtilsErrInvalidHeaders;
    1.85 +		}
    1.86 +	
    1.87 +	if (!IsValidFragment())
    1.88 +		{
    1.89 +		return KUriUtilsErrInvalidFragment;
    1.90 +		}
    1.91 +	
    1.92 +	return KErrNone;
    1.93 +	}
    1.94 +
    1.95 +/**
    1.96 +    Checks whether the given character is in Valid Set of characters.
    1.97 + 	@param		aChar A Character needs to be checked against Set of characters.
    1.98 + 	@param		aCharSet A set of Characters Descriptor.
    1.99 + 	@return 	returns ETrue if aChar is a Valid Character else returns EFalse.
   1.100 + */
   1.101 +TBool TValidatorBase::IsInCharSet(TText8 aChar, const TDesC8& aCharSet) const
   1.102 +	{
   1.103 +	for (TInt i = 0; i < aCharSet.Length(); i++)
   1.104 +		{
   1.105 +		if (aChar == aCharSet[i])
   1.106 +			{
   1.107 +			return ETrue;
   1.108 +		}
   1.109 +		}
   1.110 +	return EFalse;		
   1.111 +	}
   1.112 +
   1.113 +/**
   1.114 +    Checks whether the given descriptor is Valid or not.
   1.115 + 	@param		aDes A Descriptor needs to be checked against Set of characters 
   1.116 + 				defined in aCharTypes.
   1.117 + 	@param		aCharTypes A set of Characters Descriptor.
   1.118 + 	@param		aEscapeValid For the given aCharTypes whether the Escape encoded is valid 
   1.119 + 				or not while Validating aDes, is specified by setting ETrue or EFalse 
   1.120 + 	@return 	returns ETrue if aDes is a Valid descriptor else returns EFalse.
   1.121 + */
   1.122 +TBool TValidatorBase::IsValidCharacters(const TDesC8& aDes, TUint32 aCharTypes, TBool aEscapeValid) const
   1.123 +	{
   1.124 +	TInt len = aDes.Length();
   1.125 +	for (TInt i=0; i < len; i++)
   1.126 +		{
   1.127 +		TUint8 ch = aDes[i];
   1.128 +		// check for and decode '%' encoded characters
   1.129 +		if (aEscapeValid && ch == '%')
   1.130 +			{
   1.131 +			TInt hex;
   1.132 +			if (!EscapeUtils::IsEscapeTriple(aDes.Mid(i,3), hex))
   1.133 +				{
   1.134 +				// not a valid encoding
   1.135 +				return EFalse;
   1.136 +				}
   1.137 +			i += 2;
   1.138 +			continue;
   1.139 +			}
   1.140 +			
   1.141 +		if ((aCharTypes & KCharSetNumber) && (ch >= '0' && ch <= '9'))
   1.142 +			{
   1.143 +			continue; 
   1.144 +			} 
   1.145 +		if ((aCharTypes & KCharSetLowerAlpha) && (ch >= 'a' && ch <= 'z'))
   1.146 +			{
   1.147 +			continue; 
   1.148 +			}
   1.149 +		if ((aCharTypes & KCharSetUpperAlpha) && (ch >= 'A' && ch <= 'Z'))
   1.150 +			{
   1.151 +			continue; 
   1.152 +			}
   1.153 +		if ((aCharTypes & KCharSetAlways) && IsInCharSet(ch, KAlwaysValidChars()))
   1.154 +			{
   1.155 +			continue; 
   1.156 +			}
   1.157 +		if ((aCharTypes & KCharSetCommon) && IsInCharSet(ch, KCommonValidChars))
   1.158 +			{
   1.159 +			continue; 
   1.160 +			}
   1.161 +		if ((aCharTypes & KCharSetUser) && IsInCharSet(ch, KValidUserChars))
   1.162 +			{
   1.163 +			continue;
   1.164 +			}
   1.165 +		if ((aCharTypes & KCharSetParam) && IsInCharSet(ch, KValidParamChars))
   1.166 +			{
   1.167 +			continue; 
   1.168 +			}
   1.169 +		if ((aCharTypes & KCharSetHeader) && IsInCharSet(ch, KValidHeaderChars))
   1.170 +			{
   1.171 +			continue; 
   1.172 +			}
   1.173 +		if ((aCharTypes & KCharSetSipMark) && IsInCharSet(ch, KUriAlwaysValidSipMarkChars))
   1.174 +			{
   1.175 +			continue; 	
   1.176 +			}
   1.177 +			
   1.178 +		if ((aCharTypes & KCharSetSipPwd) && IsInCharSet(ch, KUriValidSipPwdChars))
   1.179 +			{
   1.180 +			continue; 	
   1.181 +			}
   1.182 +		
   1.183 +		if ((aCharTypes & KCharSetSipTkn) && IsInCharSet(ch, KUriValidSipToken))
   1.184 +			{
   1.185 +			continue; 	
   1.186 +			}
   1.187 +		
   1.188 +		// character is not valid so exit
   1.189 +		return EFalse;
   1.190 +		}
   1.191 +	return ETrue;
   1.192 +	}
   1.193 +
   1.194 +/**
   1.195 +	The meaning empty here is that the component is present but it's value is not present
   1.196 +	This occures when the delimeter for a component is in the URI but there is 
   1.197 +	nothing in the URI after the delimeter. For example:
   1.198 +	1. sip:loc.com		- a URI with no port
   1.199 +	2. sip:loc.com:		- a URI with a port delimeter but no port value. The port is 'empty'.
   1.200 +	3. sip:loc.com:1666	- a URI with a port
   1.201 +	
   1.202 +	@param		aDes A Descriptor.
   1.203 + 	@return		ETrue or EFalse.
   1.204 + */
   1.205 +TBool TValidatorBase::IsEmpty(const TDesC8& aDes) const
   1.206 +	{
   1.207 +	TInt len = aDes.Length();
   1.208 +	const TUint8* ptr = aDes.Ptr();
   1.209 +	if (!len && ptr)
   1.210 +		{
   1.211 +		// An entry for this item has been created so the delimeter was encountered
   1.212 +		// However, no value has been found. The item is empty
   1.213 +		return ETrue;
   1.214 +		}
   1.215 +	return EFalse;
   1.216 +	}
   1.217 +
   1.218 +
   1.219 +//
   1.220 +//		Implementatin of support for Sip-Uris as specified in RFC 3261.    //
   1.221 +//
   1.222 +
   1.223 +/**
   1.224 +	Constructor.
   1.225 + */
   1.226 +TValidatorSip::TValidatorSip(const TUriC8& aUri) 
   1.227 +: TValidatorBase(aUri)
   1.228 +	{
   1.229 +	}
   1.230 +
   1.231 +/**
   1.232 +	Checks that a Host is in a valid form as specified in RFC 3261.
   1.233 +
   1.234 +	@return		A boolean value of ETrue if uri contains valid Host,
   1.235 +				EFalse if it does not.
   1.236 + */	
   1.237 +TBool TValidatorSip::IsValidHost() const
   1.238 +	{
   1.239 +	const TDesC8& host = iUri.Extract(EUriHost);
   1.240 +	if (host.Length() == 0)
   1.241 +		{
   1.242 +		return EFalse;
   1.243 +		}
   1.244 +	
   1.245 +	// IPv4 and IPv6 hosts are validated so just check text hosts
   1.246 +	if (UriUtils::HostType(host) == UriUtils::ETextHost &&	!IsTextHostValid(host))
   1.247 +		{
   1.248 +		return EFalse;
   1.249 +		}
   1.250 +	return ETrue;
   1.251 +	}
   1.252 +	
   1.253 +/**
   1.254 +	Checks that a Port is in a valid form as specified in RFC 3261.
   1.255 +
   1.256 +	@return		A boolean value of ETrue if uri contains valid Port,
   1.257 +				EFalse if it does not.
   1.258 + */	
   1.259 +TBool TValidatorSip::IsValidPort() const
   1.260 +	{
   1.261 +	const TDesC8& port = iUri.Extract(EUriPort);
   1.262 +	if (IsEmpty(port))
   1.263 +		{
   1.264 +		return EFalse;
   1.265 +		}
   1.266 +	return IsValidCharacters(port, KCharSetNumber);
   1.267 +	}
   1.268 +	
   1.269 +/**
   1.270 +	Checks whether Userinfo contains valid characters in the sip-uri as specified in RFC 3261.
   1.271 +							
   1.272 +	@param		aUser	The descriptor to be checked.
   1.273 +	@return		A boolean value of ETrue if uri contains valid Userinfo,
   1.274 +				EFalse if it does not.
   1.275 +*/
   1.276 +TBool TValidatorSip::IsValidUser(const TDesC8& aUser) const
   1.277 +	{
   1.278 +	return IsValidCharacters(aUser, KCharSetUserAll, ETrue);
   1.279 +	}
   1.280 +
   1.281 +/**
   1.282 +	Checks whether Password contains valid characters in the sip-uri as specified in RFC 3261.
   1.283 +							
   1.284 +	@param		aPassword	The descriptor to be checked.
   1.285 +	@return		A boolean value of ETrue if uri contains valid Password,
   1.286 +				EFalse if it does not.
   1.287 +*/
   1.288 +TBool TValidatorSip::IsValidPassword(const TDesC8& aPassword) const
   1.289 +	{
   1.290 +	if (!aPassword.Length())
   1.291 +		{
   1.292 +		return EFalse;
   1.293 +		}
   1.294 +	return IsValidCharacters(aPassword, KCharSetSipPassWord, ETrue);
   1.295 +	}
   1.296 +
   1.297 +/**
   1.298 +	Checks that a UserInfo is in a valid form as specified in RFC 3261.
   1.299 +
   1.300 +	@return		A boolean value of ETrue if uri contains valid UserInfo,
   1.301 +				EFalse if it does not.
   1.302 + */
   1.303 +TBool TValidatorSip::IsValidUserInfo() const
   1.304 +	{
   1.305 +	const TDesC8& userInfo = iUri.Extract(EUriUserinfo);
   1.306 +	
   1.307 +	if (IsEmpty(userInfo))
   1.308 +		{
   1.309 +		// The '@' UserInfo sparator was found in the URI but no username/password 
   1.310 +		// is present
   1.311 +		return EFalse;
   1.312 +		}
   1.313 +	
   1.314 +	TInt separatorPos = userInfo.Locate(KUserPwdSeparator);
   1.315 +	if (separatorPos != KErrNotFound)
   1.316 +		{
   1.317 +		// seperator found so there is a username and password
   1.318 +		// the username is left of the separator
   1.319 +		if (!IsValidUser(userInfo.Left(separatorPos)))
   1.320 +			{
   1.321 +			return EFalse;
   1.322 +			}
   1.323 +		// the password is right of the separator
   1.324 +		return IsValidPassword(userInfo.Right(userInfo.Length() - separatorPos-1));
   1.325 +		}
   1.326 +		
   1.327 +	// there is no password element
   1.328 +	return IsValidUser(userInfo);
   1.329 +	}
   1.330 +
   1.331 +/**
   1.332 +	Checks whether any duplicate parameter names exist in the 
   1.333 +	whole path of the sip-uri.
   1.334 +							
   1.335 +	@param		aParamName	The descriptor to be checked.
   1.336 +	@param		aParamList	the path/parameter part of uri, which conatians all parameters and values.
   1.337 +	@return		A boolean value of ETrue if uri contains duplicate parameters,
   1.338 +				EFalse if it does not.
   1.339 +*/
   1.340 +TBool TValidatorSip::IsDuplicated(const TDesC8& aParamName, const TDelimitedParserBase8 aParamList) const
   1.341 +	{
   1.342 +	// roll back to the start of the lhs segment parser
   1.343 +	while(aParamList.Dec() != KErrNotFound) 
   1.344 +	{
   1.345 +	//Nothing to do
   1.346 +	}
   1.347 +	
   1.348 +	TPtrC8 name;
   1.349 +	TPtrC8 value;
   1.350 +	TPtrC8 segment;
   1.351 +	TInt count = 0;
   1.352 +	while( aParamList.GetNext(segment) == KErrNone )
   1.353 +		{
   1.354 +		GetNameValuePair(segment, name, value);
   1.355 +		if (aParamName.CompareF(name) == 0)
   1.356 +			{
   1.357 +			count++;
   1.358 +			}
   1.359 +		if (count > 1)
   1.360 +			{
   1.361 +			// The parameter name appears more than once in the paramter list
   1.362 +			return ETrue;
   1.363 +			}
   1.364 +		}
   1.365 +	return EFalse;	
   1.366 +	}
   1.367 +
   1.368 +/**
   1.369 +	Checks whether parameter contains valid characters in the sip-uri as specified in RFC 3261.
   1.370 +							
   1.371 +	@param		aParam	The descriptor to be checked.
   1.372 +	@return		A boolean value of ETrue if uri contains valid parameter,
   1.373 +				EFalse if it does not.
   1.374 +*/
   1.375 +TBool TValidatorSip::IsValidParam(const TDesC8& aParam) const
   1.376 +	{
   1.377 +	return IsValidCharacters(aParam, KCharSetParamAll, ETrue);
   1.378 +	}
   1.379 +
   1.380 +/**
   1.381 +	Checks whether ParamSegment contains valid characters in 
   1.382 +	Parameter name and Parameter value as specified in RFC 3261.
   1.383 +							
   1.384 +	@param		aName	The descriptor for parameter name to be checked as per RFC 3261.
   1.385 +	@param		aValue	The descriptor for value to be checked as per RFC 3261.
   1.386 +	@return		A boolean value of ETrue if uri contains valid parameters and values,
   1.387 +				EFalse if it does not.
   1.388 +*/
   1.389 +TBool TValidatorSip::IsValidParamSegment(const TDesC8& aName, const TDesC8& aValue) const
   1.390 +	{
   1.391 +	if (!aName.Length() || !IsValidParam(aName) ) 
   1.392 +		{
   1.393 +		return EFalse;	
   1.394 +		}
   1.395 +	
   1.396 +	/**************************************************************************************************************
   1.397 +	* As per RFC 3261 if the uri-parameter contains name as Tranport or User or Method then its Value must be     *
   1.398 +	* the characters as specified in Token. else if the name is Ttl then its value must lie in between 0 - 255.   *
   1.399 +	* else if the name is Maddr then its value must be a host, else if the name is lr then it must not conatin    *
   1.400 +	* any value, else it must be a other-parameter whose value must conatin the characters specified in paramchar.*
   1.401 +	* As per INC 115503 and due to IOP issue Validation of lr paramater is not performed.						  *
   1.402 +	***************************************************************************************************************/
   1.403 +	if ( ( (aName.CompareF(KTransport()) == 0 || aName.CompareF(KUser()) == 0 || aName.CompareF(KMethod()) == 0 ) 	
   1.404 +	   	   	  && !IsValidParamToken(aValue) )
   1.405 +		|| ( aName.CompareF(KTtl()) == 0 && !IsValidParamTtl(aValue) )
   1.406 +		|| ( aName.CompareF(KMaddr()) == 0  && !IsValidParamMaddr(aValue) )
   1.407 +		|| ( aName.CompareF(KTransport()) != 0 && aName.CompareF(KUser()) != 0 && aName.CompareF(KMethod()) != 0 && aName.CompareF(KTtl()) != 0 
   1.408 +			&& aName.CompareF(KMaddr()) != 0 && aName.CompareF(KLr()) != 0 && !IsValidParam(aValue))
   1.409 +		)
   1.410 +		{
   1.411 +		return EFalse;	
   1.412 +		}
   1.413 +
   1.414 +	return ETrue;
   1.415 +	}
   1.416 +
   1.417 +/**
   1.418 +	Checks whether parameters "transport", "User" and "Method" contains valid characters in the 
   1.419 +	sip-uri as specified in RFC 3261.
   1.420 +								
   1.421 +	@param		aParam	The descriptor to be checked.
   1.422 +	@return		A boolean value of ETrue if uri contains valid parameter,
   1.423 +				EFalse if it does not.
   1.424 +*/
   1.425 +TBool TValidatorSip::IsValidParamToken(const TDesC8& aParam) const
   1.426 +	{
   1.427 +	if (!aParam.Length())
   1.428 +		{
   1.429 +		return EFalse;	
   1.430 +		}
   1.431 +	return IsValidCharacters(aParam, KCharSetSipToken, EFalse);
   1.432 +	}
   1.433 +	
   1.434 +/**
   1.435 +	Checks whether parameter "ttl" contains valid characters in the sip-uri as specified in RFC 3261.
   1.436 +	
   1.437 +							
   1.438 +	@param		aParam	The descriptor to be checked.
   1.439 +	@return		A boolean value of ETrue if uri contains valid parameter,
   1.440 +				EFalse if it does not.
   1.441 +*/
   1.442 +TBool TValidatorSip::IsValidParamTtl(const TDesC8& aParam) const
   1.443 +	{
   1.444 +	if (!aParam.Length() || aParam.Length() > 3 || !IsValidCharacters(aParam, KCharSetNumber, EFalse) )
   1.445 +		{
   1.446 +		return EFalse;	
   1.447 +		}
   1.448 +	
   1.449 +	TLex8 lex(aParam);
   1.450 +	TInt address = 0;
   1.451 +	lex.Val(address);
   1.452 +	if( address > KMaxHostAddr )
   1.453 +		{
   1.454 +		return EFalse;	
   1.455 +		}
   1.456 +		
   1.457 +	return ETrue;
   1.458 +	}
   1.459 +	
   1.460 +/**
   1.461 +	Checks whether parameter "maddr" contains valid characters in the sip-uri as specified in RFC 3261.
   1.462 +							
   1.463 +	@param		aParam	The descriptor to be checked.
   1.464 +	@return		A boolean value of ETrue if uri contains valid parameter,
   1.465 +				EFalse if it does not.
   1.466 +*/
   1.467 +TBool TValidatorSip::IsValidParamMaddr(const TDesC8& aParam) const
   1.468 +	{
   1.469 +	if (!aParam.Length() && UriUtils::HostType(aParam) == UriUtils::ETextHost && !IsTextHostValid(aParam))
   1.470 +		{
   1.471 +		return EFalse;
   1.472 +		}
   1.473 +	return ETrue;
   1.474 +	}
   1.475 +	
   1.476 +/**
   1.477 +	Checks that a Path/uri-parameter is in a valid form as specified in RFC 3261.
   1.478 +	
   1.479 +	@return		A boolean value of ETrue if uri contains valid Path/uri-parameter,
   1.480 +				EFalse if it does not.
   1.481 +*/
   1.482 +TBool TValidatorSip::IsValidPath() const
   1.483 +	{
   1.484 +	const TDesC8& parameters = iUri.Extract(EUriPath);
   1.485 +	TDelimitedPathSegmentParser8 parser;
   1.486 +	parser.Parse(parameters);
   1.487 +	
   1.488 +	// sip parameters should start with a ';'
   1.489 +	if (parameters.Length() && parameters[0] != ';')
   1.490 +		{
   1.491 +		return EFalse;
   1.492 +		}
   1.493 +		
   1.494 +	TPtrC8 name;
   1.495 +	TPtrC8 value;
   1.496 +	TPtrC8 segment;
   1.497 +	while( parser.GetNext(segment) == KErrNone )
   1.498 +		{
   1.499 +		GetNameValuePair(segment, name, value);
   1.500 +		if (IsEmpty(value) || IsDuplicated(name, parser) || !IsValidParamSegment(name, value))
   1.501 +			{
   1.502 +			return EFalse;
   1.503 +		}
   1.504 +		}
   1.505 +
   1.506 +	return ETrue;
   1.507 +	}
   1.508 +
   1.509 +/**
   1.510 +	Checks whether Header contains valid characters as specified in RFC 3261.
   1.511 +							
   1.512 +	@param		aHeader	The descriptor to be checked as per RFC 3261.
   1.513 +	@return		A boolean value of ETrue if uri contains valid Header,
   1.514 +				EFalse if it does not.
   1.515 +*/
   1.516 +TBool TValidatorSip::IsValidHeader(const TDesC8& aHeader) const
   1.517 +	{
   1.518 +	return IsValidCharacters(aHeader, KCharSetHeaderAll, ETrue);
   1.519 +	}
   1.520 +	
   1.521 +/**
   1.522 +	Checks whether HeaderSegment contains valid name and values as specified in RFC 3261.
   1.523 +							
   1.524 +	@param		aName	The descriptor for Header name to be checked as per RFC 3261.
   1.525 +	@param		aValue	The descriptor for Header value to be checked as per RFC 3261.
   1.526 +	@return		A boolean value of ETrue if uri contains valid Header name and Header values,
   1.527 +				EFalse if it does not.
   1.528 +*/
   1.529 +TBool TValidatorSip::IsValidHeaderSegment(const TDesC8& aName, const TDesC8& aValue) const
   1.530 +	{
   1.531 +	if (!aName.Length() || !IsValidHeader(aName) || !IsValidHeader(aValue))
   1.532 +		{
   1.533 +		return EFalse;
   1.534 +		}
   1.535 +	return ETrue;
   1.536 +	}
   1.537 +	
   1.538 +/**
   1.539 +	Checks that a Query/Header is in a valid form as specified in RFC 3261.
   1.540 +
   1.541 +	@return		A boolean value of ETrue if uri contains valid Query/Header,
   1.542 +				EFalse if it does not.
   1.543 +*/
   1.544 +TBool TValidatorSip::IsValidQuery() const
   1.545 +	{
   1.546 +	const TDesC8& headers = iUri.Extract(EUriQuery);
   1.547 +	if (IsEmpty(headers))
   1.548 +		{
   1.549 +		return EFalse;
   1.550 +		}
   1.551 +
   1.552 +	TDelimitedQueryParser8 parser;
   1.553 +	parser.Parse(headers);
   1.554 +
   1.555 +	TPtrC8 name;
   1.556 +	TPtrC8 value;
   1.557 +	TPtrC8 segment;
   1.558 +	while( parser.GetNext(segment) == KErrNone )
   1.559 +		{
   1.560 +		// must be in the form name=value even if the value part is empty
   1.561 +		if (segment.Locate(KEqualsSeparator) == KErrNotFound)
   1.562 +			{
   1.563 +			return EFalse;
   1.564 +			}
   1.565 +		
   1.566 +		GetNameValuePair(segment, name, value);
   1.567 +		if (IsDuplicated(name, parser) || !IsValidHeaderSegment(name, value))
   1.568 +			{
   1.569 +			return EFalse;
   1.570 +		}
   1.571 +		}
   1.572 +	return ETrue;
   1.573 +	}
   1.574 +
   1.575 +/**
   1.576 +	Checks that a Fragment is in a valid form as specified in RFC 3261.
   1.577 +	Infact, SIP URIs should not contain a fragment. It it contains a 
   1.578 +	fragment then it is not a valid fragment.
   1.579 +	
   1.580 +	@return		A boolean value of ETrue if uri contains valid Fragment,
   1.581 +				EFalse if it does not.
   1.582 +*/
   1.583 +TBool TValidatorSip::IsValidFragment() const
   1.584 +	{
   1.585 +	const TDesC8& frag = iUri.Extract(EUriFragment);
   1.586 +	if (IsEmpty(frag))
   1.587 +		{
   1.588 +		return EFalse;
   1.589 +		}
   1.590 +	// SIP URIs should not contain a fragment
   1.591 +	if (frag.Length())
   1.592 +		{
   1.593 +		return EFalse;
   1.594 +		}
   1.595 +	return ETrue;
   1.596 +	}
   1.597 +
   1.598 +	
   1.599 +//
   1.600 +//	Implementatin of partial support for tel-Uris specified in RFC 3966.   //
   1.601 +//	Parsing of phone number separators as specified in RFC 3966 		   //
   1.602 +//  section 5 will not be supported. 									   //
   1.603 +//  The Implementation supports only of the form tel:36789017;isub=1411    //
   1.604 +//  It does not support lexicographical order of parameters for Validation.//
   1.605 +//
   1.606 +
   1.607 +/**
   1.608 +	Constructor.
   1.609 +	@param		aUri A reference to a parsed uri object.
   1.610 + */
   1.611 +TValidatorTel::TValidatorTel(const TUriC8& aUri) 
   1.612 +: TValidatorBase(aUri)
   1.613 +	{
   1.614 +	}
   1.615 +
   1.616 +/**
   1.617 +	Checks whether valid parameter names and values exist in the 
   1.618 +	whole path of the tel-uri.
   1.619 +								
   1.620 +	@param		aName	The descriptor for parameter name to be checked as per RFC3966.
   1.621 +	@param		aValue	The descriptor for value to be checked as per RFC3966.
   1.622 +	@return		A boolean value of ETrue if uri contains valid parameters and values,
   1.623 +				EFalse if it does not.
   1.624 + */
   1.625 +TBool TValidatorTel::IsValidParamSegment(const TDesC8& aName, const TDesC8& aValue) const
   1.626 +	{
   1.627 +	//Validation of the Name
   1.628 +	if (!aName.Length() || !IsValidCharacters(aName, KCharSetParamAll) )
   1.629 +		{
   1.630 +		return EFalse;	
   1.631 +		}
   1.632 +	//Validation of the Value based on ISDN, EXTN, Phone-context or any.
   1.633 +	if( ( KIsdnSubAddress().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetParamAll, ETrue) ) ||
   1.634 +		( KExtension().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetNumber) ) ||
   1.635 +		( KContext().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetParamAll) ) ||
   1.636 +		( KIsdnSubAddress().CompareF(aName) != 0 && 
   1.637 +		KExtension().CompareF(aName) != 0	&&
   1.638 +		KContext().CompareF(aName) != 0 &&
   1.639 +		!IsValidCharacters(aValue, KCharSetParamAll, ETrue) ) )
   1.640 +		{
   1.641 +		return EFalse;	
   1.642 +		}
   1.643 +	return ETrue;
   1.644 +	}
   1.645 +
   1.646 +/**
   1.647 +	Checks whether any duplicate parameter names exist in the 
   1.648 +	whole path of the tel-uri, and also checks whether the both ISDN and EXTN 
   1.649 +	parameters exist in tel-uri.
   1.650 +							
   1.651 +	@param		aParamName	The descriptor to be checked.
   1.652 +	@param		aParamList	the path part of uri, which conatians all parameters and values.
   1.653 +	@return		A boolean value of ETrue if uri contains duplicate parameters or 
   1.654 +				both isdn and extn parameters exist, EFalse if it does not.
   1.655 + */
   1.656 +TBool TValidatorTel::IsDuplicated(const TDesC8& aParamName, const TDelimitedParserBase8 aParamList) const
   1.657 +	{
   1.658 +	// roll back to the start of the lhs segment parser
   1.659 +	while(aParamList.Dec() != KErrNotFound) 
   1.660 +		{
   1.661 +		//do nothing
   1.662 +		}
   1.663 +	aParamList.Inc(); //To exclude phone number from the list.
   1.664 +	
   1.665 +	TPtrC8 name;
   1.666 +	TPtrC8 value;
   1.667 +	TPtrC8 segment;
   1.668 +	TInt count = 0;
   1.669 +	while( aParamList.GetNext(segment) == KErrNone )
   1.670 +		{
   1.671 +		GetNameValuePair(segment, name, value);
   1.672 +		if (aParamName.CompareF(name) == 0)
   1.673 +			{
   1.674 +			count++;	
   1.675 +			}
   1.676 +		if (count > 1)
   1.677 +			{
   1.678 +			// The parameter name appears more than once in the paramter list
   1.679 +			return ETrue;
   1.680 +			}
   1.681 +		if( ( KIsdnSubAddress().CompareF(aParamName) == 0 && KExtension().CompareF(name) == 0 ) || 
   1.682 +			( KExtension().CompareF(aParamName) == 0 && KIsdnSubAddress().CompareF(name) == 0 ) )
   1.683 +			{
   1.684 +			//Both ISDN and EXTN should not exist in Uri
   1.685 +			return ETrue;	
   1.686 +			}
   1.687 +		}
   1.688 +
   1.689 +	return EFalse;	
   1.690 +	}
   1.691 +
   1.692 +/**
   1.693 +	Checks that a path is in a valid form
   1.694 +	
   1.695 +	@return	ETrue if the path is valid otherwise EFalse
   1.696 + */
   1.697 +TBool TValidatorTel::IsValidPath() const
   1.698 +	{
   1.699 +	const TDesC8& path = iUri.Extract(EUriPath);
   1.700 +	//empty path is invalid
   1.701 +	if(!path.Length())
   1.702 +		{
   1.703 +		return EFalse;	
   1.704 +		}
   1.705 +	
   1.706 +	//Implementation of all the steps specified in section 2.5.2.2 
   1.707 +	//Validation of the path components of tel uri
   1.708 +	
   1.709 +	TDelimitedPathSegmentParser8 parser;
   1.710 +	parser.Parse(path);
   1.711 +	
   1.712 +	// tel parameters should start with a '+' or 'digit'
   1.713 +	TChar ch( path[0] );
   1.714 +	if(! (ch == '+' || ch.IsDigit()) )
   1.715 +		{
   1.716 +		return EFalse;	
   1.717 +		}
   1.718 +			
   1.719 +	TPtrC8 name;
   1.720 +	TPtrC8 value;
   1.721 +	TPtrC8 segment;
   1.722 +	//First segemnt must be telephone number
   1.723 +	if (parser.GetNext(segment) == KErrNone)
   1.724 +		{
   1.725 +		GetNameValuePair(segment, name, value);	
   1.726 +		//contains only digits
   1.727 +		if(!IsValidCharacters(name.Mid(1), KCharSetNumber))
   1.728 +			{
   1.729 +			return EFalse;	
   1.730 +			}
   1.731 +		}
   1.732 +	//Remainig all the segments
   1.733 +	while( parser.GetNext(segment) == KErrNone )
   1.734 +		{
   1.735 +		GetNameValuePair(segment, name, value);
   1.736 +		if(IsEmpty(segment))
   1.737 +			{
   1.738 +			return ETrue;	
   1.739 +			}
   1.740 +		if ( IsEmpty(value) || IsDuplicated(name, parser) || !IsValidParamSegment(name, value) )
   1.741 +			{
   1.742 +			return EFalse;	
   1.743 +			}
   1.744 +		}
   1.745 +	return ETrue;
   1.746 +	}
   1.747 +
   1.748 +/**
   1.749 +	Checks that a host is in a valid form
   1.750 +	
   1.751 +	@return	ETrue. "tel" uri does not conatin host
   1.752 + */
   1.753 +TBool TValidatorTel::IsValidHost() const
   1.754 +	{
   1.755 +	//do nothing
   1.756 +	return ETrue;
   1.757 +	}
   1.758 +
   1.759 +/**
   1.760 +	Checks that a UserInfo is in a valid form
   1.761 +	
   1.762 +	@return	ETrue. "tel" uri does not conatin UserInfo
   1.763 + */
   1.764 +TBool TValidatorTel::IsValidUserInfo() const
   1.765 +	{ 
   1.766 +	//do nothing
   1.767 +	return ETrue;
   1.768 +	}
   1.769 +
   1.770 +/**
   1.771 +	Checks that a Port is in a valid form
   1.772 +	
   1.773 +	@return	ETrue. "tel" uri does not conatin Port
   1.774 + */
   1.775 +TBool TValidatorTel::IsValidPort() const
   1.776 +	{
   1.777 +	//do nothing
   1.778 +	return ETrue;
   1.779 +	}
   1.780 +
   1.781 +/**
   1.782 +	Checks that a Query is in a valid form
   1.783 +	
   1.784 +	@return	ETrue. "tel" uri does not conatin Query
   1.785 + */
   1.786 +TBool TValidatorTel::IsValidQuery() const
   1.787 +	{
   1.788 +	//do nothing
   1.789 +	return ETrue;
   1.790 +	}
   1.791 +
   1.792 +/**
   1.793 +	Checks that a Fragment is in a valid form
   1.794 +	
   1.795 +	@return	ETrue. "tel" uri does not conatin Fragment
   1.796 + */
   1.797 +TBool TValidatorTel::IsValidFragment() const
   1.798 +	{
   1.799 +	//do nothing
   1.800 +	return ETrue;
   1.801 +	}
   1.802 +