📄 si_si.c
字号:
/*
* 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
-------
000118 (KHN) Added handling for a new type of returnInfo in the SI struct.
(i.e. SI_RETURN_EXTERNAL_NO_PARAMS)
This was made in order to recognize the situation when
an adaptor call has been made and the script is now waiting
for a result without passing back parameters to SDL.
Also added calling SI_New... functions with invokeID as a new
parameter. This was done to enable script lib functions to
call adaptorfunctions directly without having to return
parameters to SDL when it is possible to make the call in C.
**********/
#include "si_si.h"
#include "si_instr.h"
#include "si_types.h"
#include "si_libs.h"
#include "url.h"
#include "si_misc.h"
enumErrorCode ExecInstruction( pstructSI thisx )
{
BYTE instr = 0;
if (RE_ReadInstruction( thisx->RE, &instr )) {
return ExecBytecodeInstr( instr, thisx );
}
else {
/* We have reached the end of the function
without executing a return statement. This causes us to return
with an empty string (see "WML Script Spec" 30-apr 9.3.2) */
return ExecBytecodeInstr( RETURN_ES, thisx );
}
}
VOID SI_DeleteReturnParams( pstructSIReturnParams *pThis )
{
if (*pThis != NULL) {
DEALLOC( &((*pThis)->bpUrl) );
DEALLOC( &((*pThis)->funcName) );
OpS_Delete( &((*pThis)->argOpS) );
DEALLOC( pThis );
}
}
enumErrorCode SI_ExecBlock( pstructSI thisx )
{
enumErrorCode currStatus = ERR_WAE_WMLS_NONE;
if ((thisx != NULL) && (thisx->RE != NULL)) {
thisx->returnInfo = SI_RETURN_MORE; /* there is still more instructions to execute */
SI_DeleteReturnParams( &(thisx->returnParams) ); /* making sure that no old params are around */
thisx->currTime = 0; /* this is a new round of execution (a new timeslice to spend) */
while ( (thisx->currTime < thisx->timeSlice) && /* The timeslice is not used up */
(currStatus == ERR_WAE_WMLS_NONE) && /* No error has occured */
(thisx->returnInfo == SI_RETURN_MORE)) { /* The execution is not done or
needing external resources */
currStatus = ExecInstruction( thisx );
}
/*
if we need an external resource after this block then we are in a waiting state
until a result is returned to us (see SI_ReceiveReturnVal)
*/
thisx->inWaitState = (currStatus == ERR_WAE_WMLS_NONE) &&
((thisx->returnInfo == SI_RETURN_EXTERNAL) || (thisx->returnInfo == SI_RETURN_EXTERNAL_NO_PARAMS));
return currStatus;
}
else return ERR_WAE_WMLS_NULL;
}
BOOL SI_GetExtCalllParams_URL( pstructSI thisx, WCHAR **pCallUrl )
{
if ((thisx != NULL) && (*pCallUrl == NULL) &&
(thisx->inWaitState) && (thisx->returnParams != NULL) &&
( ! thisx->returnParams->islibCall) && (thisx->returnParams->bpUrl != NULL) )
{
*pCallUrl = thisx->returnParams->bpUrl;
thisx->returnParams->bpUrl = NULL;
return TRUE;
}
return FALSE;
}
BOOL SI_GetExtCalllParams_rest( pstructSI thisx, BYTE **pFuncName, pstructOpS *pArgOpS )
{
if ((thisx != NULL) && (*pFuncName == NULL) && (*pArgOpS == NULL) &&
(thisx->inWaitState) && (thisx->returnParams != NULL) &&
( ! thisx->returnParams->islibCall) && (thisx->returnParams->bpUrl == NULL) &&
(thisx->returnParams->funcName != NULL) && (thisx->returnParams->argOpS != NULL) )
{ /* NOTE: checking that bpUrl == NULL so that the callUrl has been picked up first */
*pFuncName = thisx->returnParams->funcName;
thisx->returnParams->funcName = NULL;
*pArgOpS = thisx->returnParams->argOpS;
thisx->returnParams->argOpS = NULL;
return TRUE;
}
return FALSE;
}
BOOL SI_GetLibCalllParams( pstructSI thisx, UINT16 *pLibIndex, UINT8 *pFuncIndex, pstructOpS *pArgOpS )
{
if ((thisx != NULL) && (*pArgOpS == NULL) &&
(thisx->inWaitState) &&
(thisx->returnParams != NULL) &&
(thisx->returnParams->islibCall) &&
(thisx->returnParams->argOpS != NULL) )
{
*pLibIndex = thisx->returnParams->libNbr;
*pFuncIndex = thisx->returnParams->libFuncIndex;
*pArgOpS = thisx->returnParams->argOpS;
thisx->returnParams->argOpS = NULL;
return TRUE;
}
else
{
return FALSE;
}
}
pstructVar SI_GetReturnVal( pstructSI thisx )
{
if ((thisx != NULL) && (thisx->RE != NULL)) {
return OpS_Pop( thisx->RE->OpS );
}
return NULL;
}
pstructSI SI_New( UINT8 invokeID, pstructRuntimeEnv *pRe, pUA userAgent, UINT16 timeSlice, WCHAR *base, WCHAR *referer )
{
pstructSI result;
/* taken away because so to not create memory leakage
if timeslice == 0 and the RE is lost*/
if ((*pRe != NULL) /* && (timeSlice > 0) */) {
result = NEWSTRUCT( structSI );
result->theUserAgent = userAgent;
result->invokeID = invokeID;
result->RE = *pRe;
result->timeSlice = timeSlice;
result->currTime = 0;
result->inWaitState = FALSE;
result->returnInfo = SI_RETURN_MORE;
result->returnParams = NULL;
result->WMLBrowserActionInvoked = FALSE;
result->WMLBrowser_prev = FALSE;
result->WMLBrowser_goURL = NULL;
#ifdef CAN_SIGN_TEXT
result->sc = NULL;
#endif
*pRe = NULL; /* so that the reference is not used by mistake somewhere else */
if (base != NULL)
{
result->baseURL = NEWARRAY( WCHAR, STRINGLENGTH(base)+1 );
COPYSTRING( result->baseURL, base );
}
else
{
result->baseURL = NULL;
}
if (referer != NULL)
{
result->refererURL = NEWARRAY( WCHAR, STRINGLENGTH(referer)+1 );
COPYSTRING( result->refererURL, referer );
}
else
{
result->refererURL = NULL;
}
/*
the RE was successfully created and the script file was verified.
Now the User Agent Pragmas (if any) must be handed over to the user agent.
(This handover can not be performed until verification/access checks have been made
but before actual execution of the script has started)
*/
BPI_SendUApragmasToTheUA( result->RE->BPI, result->RE->BP,
result->RE->BPend, result->theUserAgent );
return result;
}
return NULL;
}
pstructSI SI_NewWithArgString( UINT8 invokeID, BYTE* BP, UINT32 BPlen, INT16 IANAcharset,
pUA userAgent, WCHAR *baseUrl, /* this url includes funcname and arguments in the fragment */
WCHAR *refererUrl, UINT16 timeSlice, enumErrorCode *errCode )
{
pstructSI result = NULL;
pstructRuntimeEnv re = NULL;
UINT32 i;
UINT32 baseStrLen;
/* the baseUrl string will be modified by changing the '#'
to a string termination in order to save memory and performance,
thus the modification must be restored since the baseUrl is only a "loan" */
UINT32 fragmentMark = 0;
WCHAR *pwchFragment = NULL;
/* to hold the unescaped fragment (contains function name and arguments) */
WCHAR *pwchFuncNameStart = NULL;
WCHAR *pwchFuncNameEnd = NULL;
BYTE *theFuncName = NULL;
WCHAR *theArgList = NULL;
BOOL funcNameAndArgListOK = FALSE;
if (baseUrl != NULL)
{
/* first find the function name */
baseStrLen = STRINGLENGTH( baseUrl );
i = 0;
while (i < baseStrLen && ((baseUrl[i] != (WCHAR)('#'))))
{
i++;
}
if (baseUrl[i] == (WCHAR)('#'))
{ /* found the start of the fragment which contains function name and arglist */
/*
now set the fragment anchor '#' to NULL so that baseUrl string
is now only the url without the fragment
*/
baseUrl[i] = 0;
/* remember the position of the modification so we can restore it later */
fragmentMark = i;
i++; /* step past the place of the '#' */
if (i < baseStrLen)
{
pwchFragment = w_UnescapeString( &(baseUrl[i]) );
}
}
if (pwchFragment != NULL)
{
pwchFuncNameStart = pwchFragment;
/* the start of the function name was found */
/* now find the argList start paranthesis */
theArgList = pwchFragment;
while (theArgList && ((*theArgList != (WCHAR)('('))))
{
theArgList++;
}
if (*theArgList == (WCHAR)('('))
{ /* found the start of the arglist */
pwchFuncNameEnd = theArgList; /* the '(' */
theArgList++; /* step past the place of the '(' */
if (*theArgList != 0)
{ /* we have not come to the end of the string */
/*
all went ok. Now extract the function name to an US ascii string
without leading and trailing blanks
*/
/* locate real end of funcname */
while ((pwchFuncNameEnd > pwchFuncNameStart) &&
IsWhitespaceChar( *(pwchFuncNameEnd-1)) )
{
pwchFuncNameEnd--;
}
while ((pwchFuncNameStart <= pwchFuncNameEnd) &&
IsWhitespaceChar(*pwchFuncNameStart) )
{
pwchFuncNameStart++;
}
if (pwchFuncNameEnd > pwchFuncNameStart)
{ /* funcName does consist of more than blanks */
/* now check that the function name does not consist of non US-ascii chars (above 0x007F) */
i = 0;
while (((pwchFuncNameStart + i) < pwchFuncNameEnd)
&& (*(pwchFuncNameStart + i) <= 0x007F))
{
i++;
}
if ((pwchFuncNameStart + i) == pwchFuncNameEnd)
{ /* all chars valid */
/* create the funcName string */
theFuncName = NEWARRAY( BYTE, (pwchFuncNameEnd - pwchFuncNameStart)+1 );
i = 0;
while ((pwchFuncNameStart + i) < pwchFuncNameEnd)
{
theFuncName[i] = (BYTE) *(pwchFuncNameStart + i);
i++;
}
theFuncName[i] = 0; /* NULL terminate theFuncName */
/* finally done with funcName and argList!!! */
funcNameAndArgListOK = TRUE;
}
}
}
}
}
if (funcNameAndArgListOK)
{
re = RE_NewWithArgString( BP, BPlen, IANAcharset, theFuncName, theArgList, refererUrl, baseUrl, errCode );
if (re != NULL) {
result = SI_New( invokeID, &re, userAgent, timeSlice, baseUrl, refererUrl );
}
}
else
{ /* incorrect callStr (function name and/or arguments) */
*errCode = ERR_WAE_WMLS_VERIFICATION;
}
}
DEALLOC( &theFuncName );
DEALLOC( &pwchFragment );
baseUrl[ fragmentMark ] = (WCHAR)('#');
/* restore the baseUrl parameter */
return result;
}
pstructSI SI_NewWithArgOpS( UINT8 invokeID, BYTE* BP, UINT32 BPlen, INT16 IANAcharset, pUA userAgent,
BYTE **pFuncName, pstructOpS *pArgOpS, WCHAR *baseUrl, WCHAR* refererUrl,
UINT16 timeSlice, enumErrorCode *errCode )
{
pstructRuntimeEnv re = NULL;
re = RE_NewWithArgOpS( BP, BPlen, IANAcharset, *pFuncName, pArgOpS, refererUrl, baseUrl, errCode );
DEALLOC( pFuncName );
if (re != NULL) {
return SI_New( invokeID, &re, userAgent, timeSlice, baseUrl, refererUrl );
}
else
{
return NULL;
}
}
VOID SI_Delete( pstructSI *pThis )
{
if (*pThis != NULL) {
RE_Delete( &((*pThis)->RE) );
SI_DeleteReturnParams( &((*pThis)->returnParams) );
DEALLOC( &((*pThis)->baseURL) );
DEALLOC( &((*pThis)->refererURL) );
DEALLOC( &((*pThis)->WMLBrowser_goURL) );
#ifdef CAN_SIGN_TEXT
if ((*pThis)->sc)
{
ST_freeSignedContent( (*pThis)->sc );
}
#endif
DEALLOC( pThis );
}
}
BOOL SI_NewReturnParams( pstructSI thisx )
{
if (thisx != NULL) {
SI_DeleteReturnParams( &(thisx->returnParams) );
thisx->returnParams = NEWSTRUCT( structSIReturnParams );
thisx->returnParams->argOpS = NULL;
thisx->returnParams->bpUrl = NULL;
thisx->returnParams->funcName = NULL;
}
return ( (thisx != NULL) && (thisx->returnParams != NULL) );
}
VOID SI_ReceiveReturnVal( pstructSI thisx, pstructVar *pRetVal )
{
if ((thisx != NULL) && (thisx->inWaitState) && (*pRetVal != NULL))
{
OpS_Push( thisx->RE->OpS, pRetVal );
thisx->inWaitState = FALSE;
}
}
VOID SI_LoadStringDone( pstructSI thisx, INT16 charSet, BYTE **pValueStr, UINT32 strLen )
{
Lib_LoadStringDone( thisx, charSet, pValueStr, strLen );
}
VOID SI_ReceiveCalledSIReturnVal( pstructSI thisx, pstructVar *pRetVal, BOOL browserActionInvoked,
BOOL BrowserPrev, WCHAR **pBrowserGoUrl )
{
if ((thisx != NULL) && (thisx->inWaitState) && (*pRetVal != NULL))
{
OpS_Push( thisx->RE->OpS, pRetVal );
thisx->inWaitState = FALSE;
if (browserActionInvoked)
{
thisx->WMLBrowserActionInvoked = TRUE;
if (BrowserPrev)
{
DEALLOC( &(thisx->WMLBrowser_goURL) );
DEALLOC( &(thisx->WMLBrowser_goURL) );
thisx->WMLBrowser_prev = TRUE;
}
else
{
thisx->WMLBrowser_prev = FALSE;
DEALLOC( &(thisx->WMLBrowser_goURL) );
thisx->WMLBrowser_goURL = *pBrowserGoUrl;
*pBrowserGoUrl = NULL;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -