📄 si_libs.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
-------
990614 (KHN) Trouble report 113
Changes to Float.pow and sqrt were done to catch overflow and
underflow situations. When making these changes defects were
introduced which entailed that the correct result was never
returned to the stack. This has now been resolved.
(functions: Call_Float_pow and Call_Float_sqrt)
990623 (KHN) Some functions used Float.int but did not make sure the conversion
succeded. This has now been corrected.
(Functions:
Call_Lang_random,
Call_Lang_seed,
Call_String_charAt,
Call_String_subString,
Call_String_elementAt,
Call_String_removeAt,
Call_String_replaceAt,
Call_String_insertAt )
990624 (KHN) Adding float overflow detection in Float.pow and sqrt have
introduced more errors. This time a case which should
give an invalid or special value occured but then a
secondary check set the value a second time overwriting the
correct result. Now corrected.
990804 (KHN) Float.int, ceil, floor, round all check so that the float is not
larger than can be stored in an INT32. Because of bad float
precision with so large numbers the comparison let through
too big floats. This has now been corrected.
Also a problem with Flaot.round on the OSE platform has made
us rewrite the code to get rid of the use of FLOAT32_EPSILON
when performing the round. This should now be correct on all
platforms.
990824 (KHN) WMLBrowser.setVar needs a validation of the value to set the
variable to. It must be legal XML CData.
(Changed Call_Browser_setVar and
added function Setvar_checkSyntax)
990913 (FAR) Call_Browser_newContext modified
991207 (KHN) WAP 1.2 updates:
SEC-18-Jun-1999-7 and 8: String.find and String.replace behavior.
991220 (KHN) A change due to WTA:
One must check that the UA is a WTA UA otherwise the result of
the WTA call will be invalid.
000124 (KHN) Implemented the optional lib func Crypto.signText.
It is optional and is only to be existing when CAN_SIGN_TEXT is defined.
000215 (KHN) Bugfix in Call_String_subString.
Adding two integers could result in overflow that
caused incorrect behaviour.
Fixed by doing a MAX operation that will correct the overflow
000221 (KHN) Bugfix in the arrayScriptLib constant:
Fixed a missing parameter for the Call_Lang_parseInt entry.
000308 (KHN) Bugfix in the Lib_textSigned and Call_Crypto_signText functions:
Fixed calling functions with parameters of wrong types.
000308 (KHN) Replaced the usage of the following macros:
WTAI_NETWORK_COMMON
WTAI_GSM
WTAI_PDC
WTAI_IS_136
with CONFIG_WTA
000802 (KHN) Changed so that the URL.getReferer function includes the fragment
in its minimum relative path operation.
000802 (KHN) In function String.format, changed type of variable lastmatchPos to INT32.
000808 (KHN) WAP 1.2.1 update:
CR WMLSL-IBM-20000320-SeedSequence
Seed independant sequence if the seed is a negative integer.
000929 (KHN) GWC API change for Public WTAI:
CAlling Public WTAI functions are now a adaptor-connector pair.
This is from now on handled by WTAI_IF in the same way that
non-public WTAI calls are handled. This means that all
code for WMLS (both C and SDL) is the same whatever the
configuration. The files si_wtai.c and si_wtai.h are no longer
needed.
001103 (HEAD) Added support for proprietary script library functions.
This enables the GWC customer to add handling
of their own synchronous or asynchronous
library functions.
The API for this is provided through an addition
in the CLNT connector and adaptor API.
This functionality is only available if
USE_PROPRIETARY_WMLS_LIBS is defined.
**********/
#include "si_libs.h"
#include "si_var.h"
#include "si_types.h"
#include "si_misc.h"
#ifdef HAS_FLOAT
#include "si_float.h"
#endif
#include "si_int.h"
#include "url.h"
#include "wmlif.h"
/* for the parser functions */
#include "tapimmi.h"
/* for the WTA_UA define */
#include "trnscode.h"
#include "ansilibs.h"
#ifdef CAN_SIGN_TEXT
#include "si_crpto.h"
#include "aapimmi.h"
#endif
#ifdef USE_WIP_MALLOC
#include "wip_mem.h"
#endif
/* CLNTa_currentTime used by Lang.seed */
#include "aapiclnt.h"
#if defined NO_GLOBAL_VARS
#include "userdata.h"
#endif
#include "wtai_if.h"
#define STD_LIB_MAX 5
#define STD_LIB_FUNC_MAX 15
const structLibCall arrayScriptLib[6][16] =
{
{ {Call_Lang_abs, 1, 1}, {Call_Lang_min, 1, 2},
{Call_Lang_max, 1, 2}, {Call_Lang_parseInt, 1, 1 },
{Call_Lang_parseFloat, 1, 1}, {Call_Lang_isInt, 1, 1},
{Call_Lang_isFloat, 1, 1}, {Call_Lang_maxInt, 1, 0},
{Call_Lang_minInt, 1, 0}, {Call_Lang_Float, 1, 0},
{Call_Lang_exit, 1, 1}, {Call_Lang_abort, 1, 1},
{Call_Lang_random, 1, 1}, {Call_Lang_seed, 1, 1},
{Call_Lang_characterSet, 1, 0}, {NULL, 0, 0} },
{ {Call_Float_int, 1, 1}, {Call_Float_floor, 1, 1},
{Call_Float_ceil, 1, 1}, {Call_Float_pow, 1, 2},
{Call_Float_round, 1, 1}, {Call_Float_sqrt, 1, 1},
{Call_Float_maxFloat, 1, 0}, {Call_Float_minFloat, 1, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0} },
{ {Call_String_length, 1, 1}, {Call_String_isEmpty, 1, 1},
{Call_String_charAt, 1, 2}, {Call_String_subString, 1, 3},
{Call_String_find, 1, 2}, {Call_String_replace, 1, 3},
{Call_String_elements, 1, 2}, {Call_String_elementAt, 1, 3},
{Call_String_removeAt, 1, 3}, {Call_String_replaceAt, 1, 4},
{Call_String_insertAt, 1, 4}, {Call_String_squeeze, 1, 1},
{Call_String_trim, 1, 1}, {Call_String_compare, 1, 2},
{Call_String_toString, 1, 1}, {Call_String_format, 1, 2} },
{ {Call_URL_isValid, 1, 1}, {Call_URL_getScheme, 1, 1},
{Call_URL_getHost, 1, 1}, {Call_URL_getPort, 1, 1},
{Call_URL_getPath, 1, 1}, {Call_URL_getParameters, 1, 1},
{Call_URL_getQuery, 1, 1}, {Call_URL_getFragment, 1, 1},
{Call_URL_getBase, 1, 0}, {Call_URL_getReferer, 1, 0},
{Call_URL_resolve, 1, 2}, {Call_URL_escapeString, 1, 1},
{Call_URL_unescapeString, 1, 1},{Call_URL_loadString, 1, 2},
{NULL, 0, 0}, {NULL, 0, 0} },
{ {Call_Browser_getVar, 1, 1 }, {Call_Browser_setVar, 1, 2 },
{Call_Browser_go, 1, 1 }, {Call_Browser_prev, 1, 0 },
{Call_Browser_newContext, 1, 0 }, {Call_Browser_getCurrentCard, 1, 0 },
{Call_Browser_refresh, 1, 0 }, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0} },
{ {Call_Dialogs_prompt, 1, 2}, {Call_Dialogs_confirm, 1, 3},
{Call_Dialogs_alert, 1, 1}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0},
{NULL, 0, 0}, {NULL, 0, 0} }
};
#ifdef CAN_SIGN_TEXT
#define LIB_CRYPTO 6
#define FUNC_CRYPTO_SIGNTEXT 16
#define FUNC_CRYPTO_SIGNTEXT__timeCost 1
#define FUNC_CRYPTO_SIGNTEXT__nbrOfArgs 4
#endif
enumErrorCode CallLibraryFunction( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
structLibCall* theLibEntry = NULL;
if (si == NULL)
{
return ERR_WAE_WMLS_LIB;
}
if ((libIndex <= STD_LIB_MAX) && (funcIndex <= STD_LIB_FUNC_MAX))
{
theLibEntry = (structLibCall*) &( arrayScriptLib[libIndex][funcIndex] );
si->currTime += theLibEntry->timeCost;
if ((OpS_GetTopIndex( si->RE->OpS ) - theLibEntry->nbrOfArgs) < (si->RE->currF->returnSP))
{
return ERR_WAE_WMLS_STACK_UNDERFLOW;
}
if (theLibEntry->func != NULL)
{
return (theLibEntry->func)( si, libIndex, funcIndex );
}
}
#ifdef CAN_SIGN_TEXT
else if ((libIndex == LIB_CRYPTO) && (funcIndex == FUNC_CRYPTO_SIGNTEXT))
{
si->currTime += FUNC_CRYPTO_SIGNTEXT__timeCost;
if ((OpS_GetTopIndex( si->RE->OpS ) - FUNC_CRYPTO_SIGNTEXT__nbrOfArgs) < (si->RE->currF->returnSP))
{
return ERR_WAE_WMLS_STACK_UNDERFLOW;
}
return Call_Crypto_signText( si, libIndex, funcIndex );
}
#endif
else if (libIndex >= WTAI_LIB_PUB && libIndex <= WTAI_PDC_NF )
{
UINT8 nbrOfArgs = 0;
UINT16 timeCost = 1;
if ( (libIndex == WTAI_LIB_PUB) ||
((libIndex > WTAI_LIB_PUB) && (si->theUserAgent->iUserAgentMode == WTA_USER_AGENT)))
{
/* Check that the WMLS file calling a (non-public) WTAI funktion has been loaded by a WTA user agent */
if (CheckWTAIScriptCall( libIndex, funcIndex, &nbrOfArgs, &timeCost ))
{
/* That there is a corresponding WTAI function to be called via SDL over to the WTAI interface */
si->currTime += timeCost;
/* check there is enough operands on the stack for the nbr of arguments to the function */
if ((OpS_GetTopIndex( si->RE->OpS ) - nbrOfArgs) < (si->RE->currF->returnSP))
{
return ERR_WAE_WMLS_STACK_UNDERFLOW;
}
/* ok, now create the external call */
si->returnInfo = SI_RETURN_EXTERNAL;
if ( (si != NULL) && (! SI_NewReturnParams( si )) )
return ERR_WAE_WMLS_LIB;
/* the SIs returnparams struct are to be filled in */
si->returnParams->islibCall = TRUE;
si->returnParams->libNbr = libIndex;
si->returnParams->libFuncIndex = funcIndex;
si->returnParams->argOpS = OpS_NewFromOpS( si->RE->OpS, nbrOfArgs );
if (si->returnParams->argOpS == NULL)
return ERR_WAE_WMLS_LIB;
return ERR_WAE_WMLS_NONE;
}
/* else invalid will be the result (se below) */
}
/* else invalid will be the result (se below) */
}
#ifdef USE_PROPRIETARY_WMLS_LIBS
else
{
UINT8 nbrOfArgs = 0;
if ( CLNTa_hasWMLSLibFunc( libIndex, funcIndex, &nbrOfArgs ) )
{
si->currTime += 1;
/* check there is enough operands on the stack for the nbr of arguments to the function */
if ((OpS_GetTopIndex( si->RE->OpS ) - nbrOfArgs) < (si->RE->currF->returnSP))
{
return ERR_WAE_WMLS_STACK_UNDERFLOW;
}
return CallProprietaryLibraryFunction( si, libIndex, funcIndex, nbrOfArgs );
}
}
#endif
/* There is no standard library function corresponding
to the libIndex and funcIndex.
This results in an "invalid" return value */
/* NOTE!!!!!!!!!!!!!!!
Deviation from the spec:
My interpretation of the WMLS Libs spec is that
a call to a library function that does not exist (no implementation)
causes a fatal error (ERR_WAE_WMLS_LIB).
I have found it reasonable to not be so harch and instead give invalid
as a result when calling such a function. My opinion is that this leads to a
more robust and failsafe implementation. Especially since some library
functions are optional amd should this really cause a fatal error.
!!!!!!!!!!!!!!!!!!! */
{
pstructVar invalidResult = Var_New();
Var_AssignInvalid( invalidResult );
OpS_Push( si->RE->OpS, &invalidResult );
return ERR_WAE_WMLS_NONE;
}
}
enumErrorCode CallExternalLibraryFunction( pstructSI si, UINT16 libIndex, UINT8 funcIndex, UINT8 nbrOfArgs )
{
si->returnInfo = SI_RETURN_EXTERNAL;
if ( (si != NULL) && (! SI_NewReturnParams( si )) )
return ERR_WAE_WMLS_LIB;
/* the SIs returnparams struct are to be filled in */
si->returnParams->islibCall = TRUE;
si->returnParams->libNbr = libIndex;
si->returnParams->libFuncIndex = funcIndex;
si->returnParams->argOpS = OpS_NewFromOpS( si->RE->OpS, nbrOfArgs );
if (si->returnParams->argOpS == NULL)
return ERR_WAE_WMLS_LIB;
return ERR_WAE_WMLS_NONE;
}
/* Lang library *************************************************************/
enumErrorCode Call_Lang_abs( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL )) {
if (op1->type == typeInteger) {
op1->val.theInt = ABS(op1->val.theInt);
}
#ifdef HAS_FLOAT
else { /* is of type float */
op1->val.theFloat = ABS(op1->val.theFloat);
}
#endif
}
else {
Var_AssignInvalid( op1 );
}
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Lang_min( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op2 = RE_Pop( si->RE );
pstructVar op1 = RE_Pop( si->RE );
pstructVar result = Var_New();
BOOL allOk = TRUE;
#ifdef HAS_FLOAT
FLOAT32 op1val;
FLOAT32 op2val;
#endif
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (result == NULL) {
Var_Delete( &op1 );
Var_Delete( &op2 );
return ERR_WAE_WMLS_LIB;
}
/* the type checks are ONLY to take care of the requirement: max(45.0 , 45) = 45.0 */
if (op1->type != typeFloat) {
allOk = Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL );
}
if (allOk) {
if (op2->type != typeFloat) {
allOk = Var_ConvertMethod( CONVERT_INT_FLOAT, op2, NULL );
}
}
if (allOk) {
if ((op1->type == typeFloat) || (op2->type == typeFloat)) {
#ifdef HAS_FLOAT
op1val = (op1->type == typeFloat) ? (op1->val.theFloat):(op1->val.theInt);
op2val = (op2->type == typeFloat) ? (op2->val.theFloat):(op2->val.theInt);
if (op1val <= op2val) {
Var_AssignVar( result, op1 );
}
else {
Var_AssignVar( result, op2 );
}
#endif
}
else { /* both integers */
Var_AssignInt( result, (op1->val.theInt <= op2->val.theInt) ? (op1->val.theInt):(op2->val.theInt) );
}
}
if (!allOk) {
Var_AssignInvalid( result );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -