⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si_bpi.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
/*********
History
-------
990526 (KHN) Corrigendum WAG-WMLScript-28 implemented.
               Access control changes. Since access control is by default
               disabled, there is no need for a certain pragma for this and it
               has therefore been removed.
990726 (KHN) Error in BPI_New
               First the IANAcharset parameter was used to update the BPI struct's
               charset parameter. Then the BPI struct was updated and also the
               charset parameter. Then finally a charset check was made but not
               with the BPI struct as it should but instead with the IANAcharset
               parameter. This error has now been corrected.
990824 (KHN) Correction of BPI_AccessCheck:
               Now the function properly handles relative paths.
               An access path that is not relative is resolved and then the path
               is extracted.
000329 (KHN) Changes due to function name change. ReadByte -> wip_ReadByte
**********/

#include "si_bpi.h"

#include "si_types.h"
#include "url.h"
#include "wmlif.h"
#include "trnscode.h"

/******* private functions *******/


BOOL ParseAndCheckVersion( pstructBPInfo bpi, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL	allOk = TRUE;
	BYTE	version;
	BYTE	majorVersion;
	BYTE	minorVersion;

	if ( wip_ReadByte( &version, BP, BPend, pos ) )
	{
		majorVersion = (BYTE)( (version >> 4) + 1 );
		minorVersion = (BYTE)( (version & 0x0F) );

		allOk = (BOOL)( ( majorVersion == SI_MAJOR_VERSION ) && (minorVersion <= SI_MINOR_VERSION) );
	}
	else allOk = FALSE;

	if (allOk)
	{
		bpi->version = version;
	}

	return allOk;
}



BOOL ParseAndCheckSize( BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL		allOk = TRUE;
	UINT32	size = 0;

	if ( ReadMBUInt32( &size, BP, BPend, pos ) )
	{
		allOk = (BOOL)( ( size == (UINT32)(BPend - *pos) ) );
	}
	else allOk = FALSE;

	return allOk;
}


BOOL ParseAndCheckConstant( pstructBPInfo bpi, pstructConstInfo pInfo, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL		allOk = TRUE;
	UINT32	strSize;
	UINT8		constType;

  bpi = bpi;	/* to get rid of compilation warning */

	if ( ReadUInt8( &constType, BP, BPend, pos ) )
	{
		allOk = (BOOL)( constType < CONST_TYPE_MAX );
	}
	else allOk = FALSE;

	if (allOk)
  {
 		pInfo->type = (enumConstType)constType;
		pInfo->pos = *pos;

		switch(constType)
    {
    	case CONST_TYPE_INT8:
				allOk = StepBytes( sizeof(INT8), BPend, pos );
				break;

			case CONST_TYPE_INT16:
				allOk = StepBytes( sizeof(INT16), BPend, pos );
				break;

			case CONST_TYPE_INT32:
				allOk = StepBytes( sizeof(INT32), BPend, pos );
				break;

			case CONST_TYPE_FLOAT32:
				allOk = StepBytes( sizeof(FLOAT32), BPend, pos );
				break;

			case CONST_TYPE_UTF8:
			case CONST_TYPE_EXT_CHARSET:
				allOk = ReadMBUInt32( &strSize, BP, BPend, pos );
				if (allOk)
        {
					allOk = StepBytes( strSize, BPend, pos );
				}
				break;
		}
	}

	return allOk;
}


BOOL ParseAndCheckConstantPool( pstructBPInfo bpi, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL		allOk = TRUE;
	UINT16	nbrOfConsts = 0;
	UINT16	charSet = 0;
  UINT16	i;
	pstructConstInfo			pInfo = NULL;

	allOk = ReadMBUInt16( &nbrOfConsts, BP, BPend, pos );
	if (allOk)
  {
		bpi->nbrOfConstants = nbrOfConsts;
	}

	allOk = ReadMBUInt16( &charSet, BP, BPend, pos );
	if (allOk && (charSet != 0))
  {
  	/* if charSet is 0, it means that the encoding of
  	the CONST_TYPE_EXT_CHARSET is given in the WSP header.
    If no encoding is given there either, the
    default charSet will be assumed */
		bpi->characterSet = charSet;
	}

	if (allOk && (nbrOfConsts > 0))
  {
		bpi->constants = NEWARRAY( structConstInfo, nbrOfConsts );

		i = 0;
		pInfo = bpi->constants;
		while ( allOk && (i < nbrOfConsts) )
    {
			allOk = ParseAndCheckConstant( bpi, pInfo, BP, BPend, pos );
			i++;
			pInfo++;
		}
	}
	else bpi->constants = NULL;

	return allOk;
}


BOOL ParseAndCheckPragma( pstructBPInfo bpi, pstructPragmaInfo pInfo, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL							allOk = TRUE;
	UINT8							pragmaType;
	UINT16						aParam;
	UINT8							nbrOfParams;
	UINT8							i;
	enumConstType			constType;


	if ( ReadUInt8( &pragmaType, BP, BPend, pos ) )
	{
		allOk = ((BOOL)( pragmaType < PRAGMA_MAX ));
	}
	else allOk = FALSE;

	if (allOk) {

		pInfo->type = (enumPragmaType)pragmaType;
		pInfo->pos = *pos;

		switch(pragmaType) {
			case PRAGMA_ACCESS_DOMAIN:
			case PRAGMA_ACCESS_PATH:
				nbrOfParams = 1;
				break;
			case PRAGMA_UA_PROP:
				nbrOfParams = 2;
				break;
			case PRAGMA_UA_PROP_SCHEME:
				nbrOfParams = 3;
				break;
		}

		i = 0;
		while ( (i<nbrOfParams) && allOk )
    {
			allOk = ReadMBUInt16( &aParam, BP, BPend, pos );
			if (allOk)
      {
				if ( BPI_GetConstantType( bpi, aParam, &constType ) )
        {
					allOk = (BOOL)((constType >= CONST_TYPE_UTF8) &&
          	(constType <= CONST_TYPE_EXT_CHARSET));
					/* each pragma has a set of params, each param is a string constant
					a check must be made to ensure the param which is an index into the constant pool
					is a legal string constant */
				}
				else allOk = FALSE;
			}
			i++;
		}

	}

	return allOk;
}


BOOL ParseAndCheckPragmaPool( pstructBPInfo bpi, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL									allOk = TRUE;
	UINT16								nbrOfPragmas = 0;
	UINT16								i;
	pstructPragmaInfo			pInfo = NULL;

	allOk = ReadMBUInt16( &nbrOfPragmas, BP, BPend, pos );

	if (allOk) {
		bpi->nbrOfPragmas = nbrOfPragmas;
	}

	if (allOk && nbrOfPragmas) {
		bpi->pragmas = NEWARRAY( structPragmaInfo, nbrOfPragmas );

		i = 0;
		pInfo = bpi->pragmas;
		while ( allOk && (i < nbrOfPragmas) ) {
			allOk = ParseAndCheckPragma( bpi, pInfo, BP, BPend, pos );
			i++;
			pInfo++;
		}
	}
	else bpi->pragmas = NULL;

	return allOk;
}


BOOL CheckFunctionName( BYTE* funcName, UINT8 strLen )
/* checks that a UTF8 encoded string is a valid function name */
{
	UINT8		i;
	BOOL		ok = TRUE;

	ok =  ((BOOL)( ( (funcName[0] >= 'a') && (funcName[0] <= 'z') )  ||
				( (funcName[0] >= 'A') && (funcName[0] <= 'Z') )  || (funcName[0] == '_') ));

	i = 1;
	while ((i < strLen) && ok) {
		ok =  (BOOL)( ( (funcName[i] >= 'a') && (funcName[i] <= 'z') )  ||
					( (funcName[i] >= 'A') && (funcName[i] <= 'Z') )  || 
					(funcName[i] == '_') ||
					( (funcName[i] >= '0') && (funcName[i] <= '9') ) );
		i++;
	}

	return ok;
}


BOOL ParseAndCheckFunctionPool( pstructBPInfo bpi, BYTE* BP, UINT32 BPend, UINT32 *pos )
{
	BOOL		allOk = TRUE;
	UINT8		nbrOfFunc;
	UINT8		nbrOfPubFunc;		/* number of funcs in func name list */
	UINT8		funcIndex;
	UINT8		nameSize;
	UINT8		nbrOfArgs;
	UINT8		nbrOfLocVars;
	UINT32	funcSize;
	UINT8		i;

	allOk = ReadUInt8( &nbrOfFunc, BP, BPend, pos );
	if (allOk) {
		allOk = (BOOL)( nbrOfFunc > 0 );
	}

	if (allOk) {

		bpi->nbrOfFunctions = nbrOfFunc;
		bpi->functions = NEWARRAY( structFuncInfo, nbrOfFunc );

		/* Start of function name list */

		/* first start with setting funcNamePos of the functions to 0 */
		i = 0;
		while (i < nbrOfFunc) {
			bpi->functions[i].funcNamePos = 0;
			i++;
		}

		allOk = ReadUInt8( &nbrOfPubFunc, BP, BPend, pos );
		if (allOk) {
			allOk = (BOOL)( (nbrOfPubFunc > 0) && (nbrOfPubFunc <= nbrOfFunc) );
		}

		if (allOk) {
			i = 0;
			while ((i < nbrOfPubFunc) && allOk) {
				allOk = ReadUInt8( &funcIndex, BP, BPend, pos );
				if (allOk) {
					allOk = (BOOL)( funcIndex < nbrOfFunc );
				}
				if (allOk) {
					bpi->functions[funcIndex].funcNamePos = *pos;
					/* the funcNamePos is used by Accesscheck to search for the function with a certain function name */

					allOk = ReadUInt8( &nameSize, BP, BPend, pos );
				}
				if (allOk) {
					allOk = StepBytes( nameSize, BPend, pos );
					/* step the bytes to see that the BP doesn't end abruptly */
				}
				if (allOk) {
					allOk = CheckFunctionName( (BP + *pos - nameSize), nameSize );
					/* check that it is a legal func name string (UTF8 encoded) */
				}
				i++;
			}
		}

		if (allOk) {

			/* Start of functions section (func prologue and and code array)  */

			i = 0;
			while ((i < nbrOfFunc) && allOk) {
				allOk = ReadUInt8( &nbrOfArgs, BP, BPend, pos );
				if (allOk) {
					bpi->functions[i].nbrOfArgs = nbrOfArgs;

					allOk = ReadUInt8( &nbrOfLocVars, BP, BPend, pos );
				}
				if (allOk) {
					bpi->functions[i].nbrOfVars = nbrOfLocVars;

					allOk = (BOOL)( (nbrOfArgs + nbrOfLocVars) <= 256 );
				}
				if (allOk) {
					allOk = ReadMBUInt32( &funcSize, BP, BPend, pos );
				}
				if (allOk) {
					bpi->functions[i].startPos = *pos;
					bpi->functions[i].endPos = *pos + funcSize;

					allOk = StepBytes( funcSize, BPend, pos );
				}
				i++;
			}
		}
	}

	return allOk;
}


/******* end private functions **************/



/*==========================================
	BPI_Delete
============================================

---Purpose: 
To deallocate a BPI and its components.

	Note! The BPI pointer will be set to NULL after deallocation so that 
	it's not possible to use the pointer by mistake.
      
---Params:
pThis				a reference to the BPI to delete
               
---Return:


------------------------------------------------------------------------*/
VOID BPI_Delete( pstructBPInfo *pThis )
{
	if (*pThis != NULL) {
		DEALLOC( &( (*pThis)->constants ) );
		DEALLOC( &( (*pThis)->pragmas ) );
		DEALLOC( &( (*pThis)->functions ) );

		DEALLOC(pThis);
	}
}


/*==========================================
	BPI_New
============================================

---Purpose:
To create and init a BPI.
The BP will be parsed and the BPI will be filled out with all the info
that can be derived from the BP.

---Params:
BP								the bytecode package which is to be parsed
BPlen							the length (in bytes) of the BP
IANAcharset				string encoding within the BP file according to the WSP header

---Return:
pstructBPInfo			the BPI was successfully created and initialised.
NULL							the operation failed.

------------------------------------------------------------------------*/
pstructBPInfo BPI_New( BYTE* BP, UINT32 BPlen, INT16 IANAcharset )
{
	UINT32					pos = 0;
	BOOL						allOk	= TRUE;
	pstructBPInfo		bpi = NEWSTRUCT(structBPInfo);


	bpi->constants = NULL;
	bpi->pragmas = NULL;
	bpi->functions = NULL;
	bpi->characterSet = IANAcharset;
		/* a bytecode pacakage has one string encodein (UTF8, UCS2 or UCS4) */

	allOk = ParseAndCheckVersion( bpi, BP, BPlen, &pos );

	if (allOk) {
		allOk = ParseAndCheckSize( BP, BPlen, &pos );
	}

	if (allOk) {
		allOk = ParseAndCheckConstantPool( bpi, BP, BPlen, &pos );
    if (bpi->characterSet < 1)
    {
	  	/* if charSet is 0, it means that the encoding of
	  	the CONST_TYPE_EXT_CHARSET is given in the WSP header.
	    If no encoding is given there either, the
	    default charSet will be assumed (IANA_CHARSET_LATIN1).
			!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      This is a deliberate deviation from the WMLS 1.1 spec which
      says UTF-8 as the default.
      The reason for this deviation is that assuming ISO-Latin1 will never
      result in faulty strings since all values of a BYTE* string is a valid
      ISO-LATIN1 string which is not the case with UTF-8. We believe that
      this will make the interpreter more robust.
      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      */
    	bpi->characterSet = IANA_CHARSET_LATIN1;
    }
	}
	if (allOk) {
		allOk = Iana2Unicode_canConvert( bpi->characterSet );
    	/* if transcoding is not supported, verification error will occur */
	}

	if (allOk) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -