/*!
	2006/06/30	脆弱性：IPA#27428836 Fix
*/

#include "stdafx.h"
#include "UrlUtility.h"
#include "JISUtility.h"
#include "Dir.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////

CUrlUtility::CUrlUtility()
{

}

CUrlUtility::~CUrlUtility()
{

}


//	サーバパスをディレクトリパスに変換
CString CUrlUtility::GetDirectoryPath(CString serverPath)
{
	if(CPathTools::CheckSlash(serverPath))
		return(serverPath);

	int index = serverPath.ReverseFind('/');
	if(index == -1)
		return("/");
	return(serverPath.Left(index + 1));
}


//	URLのデコード(展開のみ)
CString CUrlUtility::Decode(CString url)
{
	//	展開
	CString	ret;
	int		i,binaryFlag = 0,len = url.GetLength();
	char	hex[4],*e;
	unsigned char add;
	
	for(i=0;i<len;i++)
	{
		//	日本語その他？
		if(url[i] & 0x80)
				binaryFlag = 1;

		if(url[i]=='%' && i < len - 2)
		{
			hex[0] = url[i+1];
			hex[1] = url[i+2];
			hex[2] = 0;
			
			add = (unsigned char)strtol(hex,&e,16);
			if(add != 0)
			{
				ret += add;
				i+=2;
				if(add >= 0x80)
					binaryFlag = 1;
			}
		}
		else if(url[i]=='+')
			ret += ' ';
		else
			ret += url[i];

	}

	if(binaryFlag)
		ret = CJISUtility::ToSjisString(ret);
	
	return(ret);
}

//	URLのデコード
CString CUrlUtility::DecodeUrl(CString url)
{
	//	前処理
	url.TrimLeft();
	url.TrimRight();

	//	展開
	CString	ret;
	int		i,binaryFlag = 0,len = url.GetLength();
	char	hex[4],*e;
	unsigned char add;
	
	for(i=0;i<len;i++)
	{
		//	日本語その他？
		if(url[i] & 0x80)
				binaryFlag = 1;

		if(url[i]=='%' && i < len - 2)
		{
			hex[0] = url[i+1];
			hex[1] = url[i+2];
			hex[2] = 0;
			
			add = (unsigned char)strtol(hex,&e,16);
			if(add != 0)
			{
				ret += add;
				i+=2;
				if(add >= 0x80)
					binaryFlag = 1;
			}
		}
//		else if(url[i]=='+')
//			ret += ' ';
		else
			ret += url[i];

	}

	if(binaryFlag)
		ret = CJISUtility::ToSjisString(ret);

	//	必ず"/"で始まる
	if(ret.Left(1) != '/')
		ret = '/' + ret;

	//	安全の為、\:..を排除
	int count = ret.GetLength();
	for(i=0;i<count;i++)
	{
		int rep = 0;

		rep += ret.Replace('\\','/');
		rep += ret.Replace(':','/');
		rep += ret.Replace("/./","/");			//	脆弱性：IPA#27428836 2006/06/30 Fix
		rep += ret.Replace("/../","/");
		rep += ret.Replace("//","/");
		if(rep == 0)
			break;
	}

	return(ret);
}

//	URLから、パス以外を削除
CString CUrlUtility::GetUrlObject(CString url)
{
	int index = url.Find("?");
	if(index == -1)
		return(url);
	else
		return(url.Left(index));
}

//	要求
CString CUrlUtility::GetQuery(CString url)
{
	int index = url.Find("?");
	if(index == -1)
		return("");
	else
		return(url.Mid(index + 1));
}

//	URLのエンコード
CString CUrlUtility::EncodeUrl(CString Url)
{
	int	i,len = Url.GetLength(),j=0;
	CString	ret;
	unsigned char *inUrl = (unsigned char*)Url.GetBuffer(0),*outUrl = (unsigned char*)ret.GetBuffer(Url.GetLength() * 3);


	for(i=0;i<len;i++)
	{
		if(inUrl[i] == '%')
			TRACE("Test");
		if(inUrl[i] <= 0x20 || inUrl[i] == '%' || inUrl[i] == '#')
		{
			//	危険な文字
			char	tmp[10];

			sprintf_s(tmp, 10, "%02x", inUrl[i]);
			outUrl[j++]='%';
			outUrl[j++]=tmp[0];
			outUrl[j++]=tmp[1];
		}
		else
		{
			outUrl[j++]=inUrl[i];
		}
	}
	outUrl[j]=0;

	ret.ReleaseBuffer();
	return(ret);
}

//	URLのエンコード(8ビット以上の値もエスケイプされる)
CString CUrlUtility::EncodeUrl8Bit(CString Url)
{
	int	i,len = Url.GetLength(),j=0;
	CString	ret;
	unsigned char *inUrl = (unsigned char*)Url.GetBuffer(0),*outUrl = (unsigned char*)ret.GetBuffer(Url.GetLength() * 3);


	for(i=0;i<len;i++)
	{
		if(inUrl[i] <= 0x20 || inUrl[i] == '%' || inUrl[i] == '#' || inUrl[i] >= 0x80)
		{
			//	危険な文字
			char	tmp[10];

			sprintf_s(tmp, 10, "%02x", inUrl[i]);
			outUrl[j++]='%';
			outUrl[j++]=tmp[0];
			outUrl[j++]=tmp[1];
		}
		else
		{
			outUrl[j++]=inUrl[i];
		}
	}
	outUrl[j]=0;

	ret.ReleaseBuffer();
	return(ret);
}
