Integration
SDK 5.00x Errata
Fixes Affecting Users of the ScriptEase
ISDKs
5.00x
errate are no longer being actively released.
5.00x users should upgrade to 5.01 and view errata
at the page: Integration
SDK 5.01x Errata
- 5.00f
API - latest update : September
17,
2003
API
Errata, version 5.00f
New, September
17,
2003
API Errata, version 5.00e
New, February 14, 2003
API Errata, version 5.00d
New, November 13, 2002
API Errata, version 5.00c
New, August 13, 2002
API Errata, version 5.00b
New, April 17, 2002
API Errata, version 5.00a
New, March 7, 2002
The
Details
for
5.00f -- (may apply to earlier versions)
- hang
on assigning to undefined variable if global
object is SE_DYNA_UNDEF
(for ISDK/C 5.00f)
Bug:
If the global object is dynamic (i.e. setSetCallbacks
has been called on SE_GLOBAL), and if jseopt.h
defines JSE_CACHE_GLOBAL_VARS, and if a property
of the global is of type undefined, then assigning
to that property will result in an assertion
being raised (if a debug build) or in the engine
haning in an infinite loop.
Fix:
In src/core/call.c, function secoreFindAnyVar(),
at about line 1899, change this code:
# if JSE_DYNAMIC_CALLBACKS==1
if ( obj_flag==0 || VUndefined != SEVAR_GET_TYPE(wslot) )
# endif
to
this
# if JSE_DYNAMIC_CALLBACKS==1
if ( !(obj_flag==0 || VUndefined != SEVAR_GET_TYPE(wslot)) )
wslot = STACK0;
else
# endif
- Alignment
errors with Clib *printf and *scanf floating-point
on HP-UX
(for ISDK/C 5.00f)
Bug:
If a call to the Clib *printf or *scanf methods
(e.g. Clib.sprintf) contains non-floating-point
data types following a floating-point type,
data alignment may be incorrect and invalid
data or crashes will result. This problem appears
only on HPUX systems.
Fix:
Replace src/lib/clib/sefmtio.c with the file
at ftp://ftp.nombas.com/pub/isdkeval/se500/sefmtio.c
- system
can become corrupted if number of objects in
use is greater than MARK_STACK_SIZE
(for ISDK/C 5.00f)
Bug:
If the number of objects in use is greater than
MARK_STACK_SIZE (defined in call.h) then memory
may become corrupted. This is a rare oocurence
and very difficult to duplicate. If you have
experienced such corruption when running with
very many objects, and if the problem is difficult
to duplicate, then this may be the cause.
Fix:
In src/core/garbage.c, function mark(), this
block near line 936:
for( i=0;i<used;i++ )
{
rSEVar var;
var = &SEMEMBERS_GET(basecall,mems,i,value);
should
become:
for( i=0;i<used;i++ )
{
rSEVar var;
seVarName vn = SEMEMBERS_GET(basecall,mems,i,name);
if( SE_NO_VARNAME != vn
&& IsNormalSEStringTableEntry(vn)
&& 0 == (HashListFromSEVarName(vn)->locks & JSE_SESTRING_SWEEP_BIT) )
{
add_it = TRUE;
break;
}
var = &SEMEMBERS_GET(basecall,mems,i,value);
- when
converting numbers to strings, rounding will
not occur in some locales
(for ISDK/C 5.00f)
Bug:
In locales that use a comma to separate fractional
parts of floating-point numbers (e.g. 3,145).
JSE_NUMTOSTRING_ROUNDING will not round.
Fix:
In src/misc/utilstr.c, function EcmaNumberToString(),
at around line 979, this statement:
if ( NULL == (decimal=strchr_sechar((secharptr)buffer,'.')) )
should
become:
if ( NULL == (decimal=strchr_sechar((secharptr)buffer,'.'))
&& NULL == (decimal=strchr_sechar((secharptr)buffer,',')) )
- semicolon
required after assignment of function literals
(for ISDK/C 5.00f)
Bug:
An error may be generate after a script line
iniating a function literal, as in this example:
var a = function() { return; } // compiler says semicolon needed here
var b = function() { return; }
Fix:
In src/core/expressn.c, function secompilePrimaryExpression(),
at around line 3022, add this as the last statement
(before the break) for "case seTokFunction:":
This->last_token = NULL;
and
in src/core/statemnt.c, function secompile_semicolon(),
change the "else if" statement at
about line 49 to:
else if ( !This->automatic_semicolon_insertion
|| ( NULL != This->last_token
&& seTokEOL != tokType(This->last_token)
&& seTokEOF != tokType(This->token)
&& '}' != tokType(This->token) ) )
- Invalid
conversion of strings to number on PalmOS when
strings ends in decimal point
(for ISDK/C 5.00f)
Bug:
On the PalmOS, a string ending in a decimal
point is not recognized as a valid number. For
example the following would evaluate as false:
"4." == 4
Fix:
In src/misc/palmos/crt/string/string.c function
strtod_sechar(), at about line 126 replace this
code:
if ( isdigit_sechar(*(nptr+1)) )
nptr++;
with:
if ( isdigit_sechar(*(nptr+1)) || IS_WHITESPACE(*(nptr+1)) )
nptr++;
- conversion
of strings to numeric sestrings may make non-unique
identifiers
(for ISDK/C 5.00f)
Bug:
When string identifiers are converted to sestrings
(the internal representation of all identifiers),
some strings may be wrongly treated as if they
were integer indices and may produce non-unique
internal identifiers. Exactly when this happens
depends on compilers and hardware and how they
treat the ascii character set. The results of
this problem may be exceedingly rare (requiring
two unusual string names to collide), hard to
trace to this source problem (error will likely
occur long after the collision has been made),
and severe (crash is likely).
Fix:
In src/core/util.c replace the function CreateSEVarName()
with with the file at ftp://ftp.nombas.com/pub/isdkeval/se500/createsevarname.c
- global
VariableObject (activation) is not adjusted
if global object changes
(for ISDK/C 5.00f)
Bug:
If the VariableObject is the same as the global
object (i.e. in global scope) and the global
object is changed the variable object retains
its old value.
Fix:
In src/core/se500.c, function sePutMember(),
change code at about line 2603 from:
if( SEVAR_GET_TYPE(tmp)==SE_TYPE_OBJECT )
{
HSEOBJECT_ASSIGN(CALL_GLOBAL(call),SEVAR_GET_OBJECT(tmp));
}
to:
if( SEVAR_GET_TYPE(tmp)==SE_TYPE_OBJECT )
{
if ( CALL_VAROBJ(call) == call->hGlobalObject )
HSEOBJECT_ASSIGN(CALL_VAROBJ(call),SEVAR_GET_OBJECT(tmp));
HSEOBJECT_ASSIGN(CALL_GLOBAL(call),SEVAR_GET_OBJECT(tmp));
}
- Function
constructor may fail if dynamic global object
overrides getters and putters
(for ISDK/C 5.00f)
Bug:
If the function constructor is called to make
an anonymous function, and if the global object
is dynamic and the getters and putters do not
accept "anonymous" as a real variable,
then no function is created.
Fix:
In src/lib/ecma/seobject.c function Ecma_Function_construct(),
at about line 292 add these local variables:
const struct seObjectCallbacks * save_global_callbacks;
const struct seObjectCallbacks * save_activation_callbacks;
and
then at about line 325, after the final call
to add_to_buffer(..) and before the call to
seExists(), insert this block:
/* it is possible that global behavior has been overloaded - temporarily disable that */
save_global_callbacks = seGetCallbacks(se,SE_GLOBAL,SE_VALUE);
if ( NULL != save_global_callbacks )
seSetCallbacks(se,SE_GLOBAL,SE_VALUE,NULL);
save_activation_callbacks = seGetCallbacks(se,SE_ACTIVATION,SE_VALUE);
if ( NULL != save_activation_callbacks )
seSetCallbacks(se,SE_ACTIVATION,SE_VALUE,NULL);
and
finally add this block at the end of the function
(around line 401):
/* restore previous global callbacks */
if ( NULL != save_activation_callbacks )
seSetCallbacks(se,SE_ACTIVATION,SE_VALUE,save_activation_callbacks);
if ( NULL != save_global_callbacks )
seSetCallbacks(se,SE_GLOBAL,SE_VALUE,save_global_callbacks);;
- seBrowserCreateEvent,
in browser framework, always makes an undefined
event
(for ISDK/C 5.00f)
Bug:
The seBrowserCreateEvent() function, for creating
HTML browser events if using our browser framework,
is ignoring the specified event text and always
creating an undefined event.
Fix:
In src/browser/sebrowse.c function seBrowserCreateEvent(),
at about line 1304 change:
ret = seEval(se,func,SE_FUNC,NULL,NULL,SE_DEFAULT,¶ms);
to:
ret = seEval(se,func,SE_FUNC,NULL,stack,SE_DEFAULT,¶ms);
then
at about line 1329 change:
sePutObject(se,loc,SE_UNIMEM(eventname),func);
to:
seMustPutDirectObject(se,loc,SE_UNIMEM(eventname),func);
finally
at about line 1333 change:
seFreeObject(se,loc);
to:
if ( loc ) seFreeObject(se,loc);
- SEObjectWrapper
has too many contexts; may be NULL
(for ISDK/C 5.00f)
Bug:
The SEObjectWrapper class, used for auto-wrapping
C++ classes, defines two fields to hold the
current context. They are not both updated together
and one may be NULL when needed. This may cause
a crash if the NULL value is used.
Fix:
In src/app/jseobject.h and src/app/jseobject.cpp,
the SEObjectWrapper class defines two members
to save the current context, m_context and m_execContext.
There should only be one such member. In src/app/jseobject.h
definitiion of the SEObjectWrapper class remove
the m_execContext member, and move the m_context
member under "private:". Then change
all references of m_execContext to m_context.
Also, in src/app/jseobject.cpp remove the constructor
initializers for m_execContext().
- Socket()
should return null on error
(for ISDK/C 5.00f)
Bug:
If a call to Socket() fails it should return
null (as documented). Currently it is always
returning an object.
Fix:
In src/lib/socket/sesocket.c replace the Socket_call
method with this code:
static SE_CALLBACK(void)
Socket_call(secontext se,sememcount argc)
{
seobject obj = seMakeObject(se);
buildSocketObject(se,argc,obj);
if ( NULL == sePtrFromObj(se,obj,SESOCKET_PTR_NAME,False) )
sePutNull(se,SE_RETURN,SE_VALUE);
else
sePutObject(se,SE_RETURN,SE_VALUE,obj);
}
- Memory
corruption on %s error messages
(for ISDK/C 5.00f)
Bug:
If an error messages is generated with a format
string containing the "%s" formatting
type, and if the string that %s refers to is
very long, then an assert will be generated
(in debug mode), or a memory-overwrite will
likely cause a crash (in release mode). For
example, this script would cause such a crash:
var bigstr = "func";
for (var i = 0; i < 5000; i++ )
bigstr += "x";
bigstr += "()";
eval(bigstr);
This
can also be a problem if you are using %s in
any of your seThrow() calls but are not limiting
the length of string arguments.
Fix:
In the next release (5.00g) the handling for
error messages has been adjusted to manage arbitrarily
long parameters. But for 5.00f the quickest
and safest approach is to edit the files src/core/rsrccore.h
and src/lib/common/rsrclib.h and change all
occurences of "%s" in those files
to be "%.30s". If you are using a
build that relies on our implementation of se_vsprintf
in src/misc/utilstr.c (if your system does not
supply a native implementation of vsprintf)
then contact http://support.nombas.com/ for
a replacement function.
- Clib.strtok()
fails with seShareReadObject()
(for ISDK/C 5.00f)
Bug:
If the Clib object is shared in multiple thread
via seShareReadObject() and the Clib.strtok()
method is called then data will be corrupted.
Fix:
Replace src/clib/sestring.c with the file at
ftp://ftp.nombas.com/pub/isdkeval/se500/sestring.c
- JSE_ALWAYS_IMPLICIT_*
flags are not applied to global code
(for ISDK/C 5.00f)
Bug:
The descriptions for JSE_ALWAYS_IMLICIT_THIS
and JSE_ALWAYS_IMPLICIT_PARENTS say that all
functions will act is if they had the SE_IMPLICIT_THIS
and SE_IMPLICIT_PARENTS flag set. But this is
not happening with the global script code (which
may be seen as code within a global initialization
function).
Fix:
A simple fix is to use SE_INIT_IMPLICIT_THIS
and SE_INIT_IMPLICIT_PARENTS flags in your call
to seEval(). Otherwise, to fix this in the ScriptEase
code locate these lines in src/core/call.c,
function callFunction, near line 634:
# if JSE_ALWAYS_IMPLICIT_PARENTS==1
/* all function have this assumed automatically, except for the initialization */
if ( !isinit || (func->attributes & SE_IMPLICIT_PARENTS) )
# else
and
replace with this code
# if JSE_ALWAYS_IMPLICIT_PARENTS==0
if( func->attributes & SE_IMPLICIT_PARENTS )
and a few lines down, replace this block:
# if JSE_ALWAYS_IMPLICIT_THIS==1
/* all function have this assumed automatically, except for the initialization */
if ( !isinit || (func->attributes & SE_IMPLICIT_THIS) )
# else
with:
# if JSE_ALWAYS_IMPLICIT_THIS==0
if( func->attributes & SE_IMPLICIT_THIS )
- eval("var
x = 100") returns undefined
(for ISDK/C 5.00f)
Problem:
eval() is supposed to return the result of the
last expression evaluated. But in the case of
the last expression being a variable initializer
(e.g. "var x = 10") the return from
eval() or seEval() will be undefined. We put
this behavior in to match what happens in the
popular browsers. But this does not appear to
be correct behavior accoding to the ECMA specification,
nor according to major boooks on the language,
nor according to common sense (eval("var
x; x=10") returns 10 so why shouldn't eval("var
x=10") do the same?).
Fix:
In src/core/statemnt.c, function secompileVar(),
locate the comment around line 228 beginning
with "/* we don't do anything with the
value" and replace with this block:
#if SE_ECMA_RETURNS==1
#if defined(SE_VARINIT_NO_RETURN)
/* we don't do anything with the value - note I've checked the
* browsers and while something like 'a = 15;' will auto-return
* 15, 'var a = 15;' does not. Therefore, it is incorrect to put
* a seSaveExpr here.
*/
#else
secompileGetValue(This);
SEASSERT( This->expr.type==EXPR_STACKTOP );
if( LOCAL_TEST_IF_INIT_FUNCTION(This->locfunc) )
secompileAddItem0(This,seSaveExpr);
#endif
#endif
If
you need the browser-like behavior, so that
eval("var x=10") returns undefined,
just define SE_VARINIT_NO_RETURN
and recompile.
- seContinueFunc
callback does not remove temporaries
(for ISDK/C 5.00f)
Bug:
If temporary objects or strings are created
in your seContinueFunc callback (e.g. via seMakeObject,
seGetString, etc...) then those temporaries
are not automatically cleaned up when your the
seContinueFunc callback returns (as is suggested
by our documentation on Lifetime rules). This
can lead to growing use of memory as your program
runs.
Fix:
In src/core/srccore.h remove all CALL_CONTINUE
and callMayIContinue macros, to be replaced
with this function prototype:
sebool callMayIContinue(struct seCall *call);
and
in src/core/call.c add the callMayIContinue()
function found at ftp://ftp.nombas.com/pub/isdkeval/se500/callmayicontinue.c:
- SElib.dynamicLink()
expects string lengths to remain constant
(for ISDK/C 5.00f)
Bug:
If a DLL (or shared object or code fragment)
receives a string datum from SElib.dynamicLink()
and changes the data in that string so that
its length is shorter than the original string,
we will assume the length has not changed and
store data beyond the end of the string into
the passed parameter. In Unicode and ASCII builds
this will just leave the string length incorrect.
In MBCS builds this could potentially cause
a failure if the data beyond the null character
is invalid MBCS sequences.
Fix:
In src/lib/common/sedyna.c, function CallDynamicFunction(),
at about line 245 change the statement from:
sePutString(se,SE_ARGS,SE_INDEX((sememcount)(i+first_parameter)),\
(secharptr)data,BufferLengths[i]);
to:
sePutString(se,SE_ARGS,SE_INDEX((sememcount)(i+first_parameter)),\
(secharptr)data,SE_PS_STRLEN);
- bad
error message, or crash, when "goto"
statement is not followed by a label
(for ISDK/C 5.00f)
Bug:
If a goto is compiled, but is not followed by
a proper label, then the error message will
be invalid, may display garbage, and may crash.
Fix:
In src/core/statemnt.c, function secompileStatement(),
in the "case seTokGoto:" change line
1069 from:
callQuit(call,textcoreGOTO_LABEL_NOT_FOUND);
to:
callQuit(call,textcoreNOT_LOOP_LABEL);
- "goto"
is not standard EcmaScript
(for ISDK/C 4.40f)
Issue:
ScriptEase implements the "goto" statement,
but most other EcmaScript implementations do
not recognize the keyword.
Fix:
To disable the "goto" keyword, in
srccore/codeprt2.c function GetVariableNameOrKeyword(),
at about line 478, change this line:
if ( -1 != find )
to:
if ( -1 != find
# if defined(JSE_DISABLE_GOTO)
&& find != textcoreKeyword_goto
# endif
)
Then,
if you want to disable the "goto"
keyword, compile with JSE_DISABLE_GOTO defined.
(JSE_DISABLE_GOTO will be added as a standard
options to jseopt.h in the next release).
- cached
prototypes (Array, Function, Object, String)
miss __parent__ inheritance
(for ISDK/C 5.00f)
Bug:
Some common objects have their Object.prototype
object cached for faster access. These objects
are Array,
Function,
Object,
and String.
When refreshing this "prototype cache"
the real objects may not be found if inheritance
is through the __parent__ chain instead of through
standard _prototype chain. The resulting bug
will usally be that statements that use these
cached prototypes (e.g. new String(),
"foo".toString())
will fail, while objects that do not use this
cache (e.g. new Date())
will work.
Fix:
The function AssignGlobalPrototype() in src/core/call.c
should be replaced with the version found at
ftp://ftp.nombas.com/pub/isdkeval/se500/assignglobalprototype_500f.txt
- try/catch
grows internal stack
(for ISDK/C 5.00f)
Bug:
Each try/catch will leave one element on the
internal stack. The stack space is restored
whenever the containing function returns. But
if the function does not return then many try/catch
blocks will eventually throw an out-of-stack
error. For example, the following script would
eventually exhause internal stack space:
for ( ; ; )
{
try
{
throw "blah";
}
catch(e)
{
}
}
Fix:
In src/core/operator.c, function secode_ReasonToQuit(),
remove all 3 lines declaring or referencing
the variable w_new_loc.
These are near lines 885, 893, and 898.
- seCreateFiber()
with JSE_SECURE uses unreleased memory
(for ISDK/C 5.00f)
Bug:
If compiling with JSE_SECURE defined, then each
call to seCreateFiber() allocates about 32 bytes
that are not released until the top-level context
is destroyed.
Fix:
The simplest fix is to remove JSE_SECURE from
your JSEOPT.H file. If compiling with JSE_TASK_SCHEDULER
and JSE_SECURE then in src/core/util.c, function
callNewSettings(), at about line 1202 replace
this line:
if( success && (call->prev == NULL ||
with:
if( success && ((call->prev == NULL && call->fiber_prev==NULL)||
- COMOBJ
leaks resources
(for ISDK/C 5.00f)
Bug:
COMOBJ can leaks resources when working with
type libraries and pass-by-ref COM objects.
Over time total memory use will grow.
Fix:
Replace src/lib/comobj/* code with files found
at ftp://ftp.nombas.com/pub/isdkeval/se500/comobj_2003_03_20.zip
- #define
prevents rest of script from being interpreted
(for ISDK/C 5.00f)
Bug:
When interpreting a script from text, the #define
directive causes the rest of the script to be
ignored.
Fix:
In src/core/define.c, function defineProcessSourceStatement(),
around line 237 (right at end of the for loop,
after the else block) add this code:
/* Check if we have reached the end of the line */
if ( SECHARPTR_GETC(c) == '\n' || SECHARPTR_GETC(c) == '\r' )
{
end = c; break;
}
# if JSE_UNICODE==1
if ( SECHARPTR_GETC(c) == 0x2028 || SECHARPTR_GETC(c) == 0x2029 )
{
end = c; break;
}
# endif
- Empty
#defines can cause errors on expansion
(for ISDK/C 5.00f)
Bug:
If a preprocessor macro is defined without a
body, then errors can occur when that macro
is expanded in the script.
Fix:
In src/core/source.c, function sourceNewFromText(),
around line 380 change this block:
if ( !sourceNextLine(This,call,False,&success,True)|| !success )
{
sourceDelete(This,call);
return NULL;
}
to:
sourceNextLine(This,call,False,&success,True);
if ( !success )
{
sourceDelete(This,call);
return NULL;
}
- The
#ifdef and #ifndef preprocessor directives behave
incorrectly
(for ISDK/C 5.00f)
Bug:
The #ifdef and #ifndef directives rely on comparisons
against the ECMAScript undefined value to determine
if a symbol is defined. This behavior causes
errors when the directive is applied to an empty
macro. These directives now only test names
in respect to whether or not they have been
defined by #define, or are members of the SE_DEFINE
object.
Fix:
In src/core/source.c, function sourceConditionalCompilationFilter(),
around line 769 change this line:
if ( !sourceEvaluateConditionalCompilation(This,call,\
SourceToEvaluate,textcoreCCD_ifdef==find,True) )
to:
if ( !sourceEvaluateIfdef(This,call,SourceToEvaluate,textcoreCCD_ifdef==find) )
Next,
the sourceEvaluteIfdef() function needs to be
added to src/core/source.c. The source for this
function can be found at ftp://ftp.nombas.com/pub/isdkeval/se500/ifdef.c
for
5.00e -- (may
apply to earlier version)
- seParseVar()
result may become invalid if SE_GLOBAL changes
(for ISDK/C 5.00e)
Bug: If the object returned by seParseVar()
represents the current SE_GLOBAL, then that
object will only be correct until SE_GLOBAL
is assigned to a new value. This is because
seParseVar is returning the SE_GLOBAL shortcut
itself, and not a lock on the existing object
that is represented by SE_GLOBAL.
Fix:
Replace seParseVar() function in src/core/se500.c
with the version found at ftp://ftp.nombas.com/pub/isdkeval/se500/separsevar.c
- seParseVar(...SE_VP_CREATE)
is not making sub-properties of objects
(for ISDK/C 5.00e)
Bug: According to the documentation, seParseVar()
with the SE_VP_CREATE flag should create any
members that do not already exist, but this
is not happening if the members are more than
one level deep. For example, seParseVar(..."yabba.dabba.doo"...SE_VP_CREATE)
will generate a ConversionError if "yabba"
does not already exist.
Fix:
In src/core/se500.c, functions seParseVar(),
at about line 3132 (3 lines below the "got_name:"
tag), this block:
if( flags&SE_VP_CREATE )
{
seConvert(se,obj,SE_STR(mem),SE_TOOBJECT);
}
should
be replaced by this block:
if( flags&SE_VP_CREATE )
{
if( seGetType(se,obj,SE_STR(mem))==SE_TYPE_UNDEFINED )
{
seobject tmpobj = seMakeObject(se);
sePutObject(se,obj,SE_STR(mem),tmpobj);
seFreeObject(se,tmpobj);
}
else
{
seConvert(se,obj,SE_STR(mem),SE_TOOBJECT);
}
}
- stack
corruption with long mode parameter to Clib.fopen()
and Clib.freopen()
(for ISDK/C 5.00e)
Bug: If the mode parameter to Clib.fopen() or
Clib.freopen() parameter is longer than 18 characters,
a stack buffer overflow will occur.
Fix:
In src/lib/sestdio.c, functions Clib_fopen()
and Clib.freopen() change this line (at about
line 671 and 737)
strcpy_sechar((secharptr)NewMode,Mode);
to
this
memset(NewMode,0,sizeof(NewMode));
strncpy_sechar((secharptr)NewMode,Mode,sizeof(NewMode)/sizeof(NewMode[0])-2);
- PalmOS
samples treat seInitialize() as a boolean
(for ISDK/C 5.00e)
Problem: The PalmTst and EvalBox samples treat
the return value from seInitialize() as a boolean,
assuming zero indicates error and non-zero indicates
success. This can cause an invalid seInitialize(),
such as if the SEISDK or MathLib PRCs are not
loaded, to be mis-interpreted as a successful
load of the engine. Instead, seInitialize(),
as documented, returns a uint
indicating the version of the engine that is
initializing. In recent release more distinct
values are returned from seInitialize() to help
determine what part of initialization failed--the
invalid return value use to be only 0, which
is why treating seInitialize() as a boolean
has worked on previous releases.
Fix:
In samples/evalbox/palmos/evalbox.c the test
on seInitialize() should change from
ErrFatalDisplayIf( (!seInitialize(&gSEFuncTable)),
to
ErrFatalDisplayIf( (SE_ENGINE_VERSION_ID!=seInitialize(&gSEFuncTable)),
Also,
in tests/testers/build/palmos/palmtst.c, the
results of seInitialize() should be assigned
to a uint
ver; local variable, and the ErrFatalDisplayIf()
first argument should change from (!success)
to (ver!=SE_ENGINE_VERSION_ID).
- seEnd()
terminating an seEval(...SE_FUNC|SE_START...)
asserts
(for ISDK/C 5.00e)
Bug: Using seEnd() to terminate an seEval using
the SE_FUNC option (and SE_START obviously)
will cause asserts to trigger.
Fix:
In src/core/se500.c, after this line (which
is found at about line 6140):
struct evalFuncStart *info;
add
the following block:
while( call->start_info->done_with_func!=FRAME )
{
callReturnFromFunction(call);
}
- SEDBC
Database methods assume an open database
(for ISDK/C 5.00e)
Bug: Some methods of the Database object assume
that the .connect() method succeeded. If .connect()
did not succeed then these methods may crash.
It may be considered bad programming for a script
to call these methods after connect failed,
but a script language should be able to recover
from "bad programming".
Fix:
Replace src/lib/sedbc/database.c with the file
found at ftp://ftp.nombas.com/pub/isdkeval/se500/database.c
- Bug
in seIsFunc() or seFunctionAsText() if out-of-memory
(for ISDK/C 5.00e)
Bug: If an out-of-memory condition occurs while
caling seIsFunc() or seFunctionAsText(), then
invalid memory may be referenced and a possible
crash.
Fix:
In src/core/se500.c, function seIsFunc(), at
about line 4369, add to this conditional
if( hobj )
so
it becomes
if( hobj && !IS_OUT_OF_MEM_OBJ(call,hobj) )
- Typo
in seEval() errata
(for ISDK/C 5.00e)
Bug: An earlier 5.00e errata mistakenly placed
a semi-colon at the end of an if clause. The
semi-colon could cause invalid stack use, especially
with the SE_START
flag.
Fix:
That previous errata has been updated here:
seEval(..SE_START...) will
grow stack if compilation error
- RegExp.$x
and RegExp.lastParen not overwriting previous
results with "undefined"
(for ISDK/C 5.00e)
Bug: When the results of a regular expression
call should result in undefined
for for
RegExp.$1...RegExp.$9 or RegExp.lastParen,
the results of the most-recent previous call
are not over-written with undefined.
Fix:
In src/lib/ecma/seregexp.c, function RegExp_ExecOrCallOrTest(),
the three calls to sePutUndefined(...)
(at lines 623, 673, and 690) should be replaced
with seMustPutUndefined(...).
- array
sort return invalid when array.length==1
(for ISDK/C 5.00e)
Bug: If array.length==1,
then array.sort()
will return undefined.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Array_sort(),
the code (near line 913) for "<=1"
elements should be changed to:
if( num_items <= 1 )
{
seAssign(se,SE_RETURN,SE_VALUE,SE_THIS,SE_VALUE);
return;
}
- Allocation
error during compilation may leave some identifiers
locked
(for ISDK/C 5.00e)
Bug: If memory allocation fails during compilation,
it is possible for local identifiers to remain
locked or not immediately freed.
Fix:
In src/core/loclfunc.c, function loclAddVarName(),
near line 303 -1 is being returned without calling
RemoveVarNameLock() to free the recent lock
on that varname. That code should instead be:
if( new_items==NULL )
{
RemoveVarNameLock(name);
return (uword16)(-1);
}
- In
Unicode builds, size of Buffer and BLOb objects
is miscalculated
(for ISDK/C 5.00e)
Bug: When building with JSE_UNICODE, the size
of Buffer and BLOb objects is being doubled
erroneously. This can show up in basic BLOb
methods, or in conversion methods of functions
such as Clib.fwrite and SElib.dynamicLink.
Fix:
In src/lib/common/seblob.c, function blobLength(),
at about line 586 the type>=0
case shoulod be reduced to this:
if( type >= 0 )
{
return (SE_POINTER_UINDEX) type;
}
- Error
in timezone calculation for Windows CE
(for ISDK/C 5.00e)
Bug: Timezone offset from GMT is miscalculated
in the Date object in Windows CE.
Fix:
In src/lib/ecma/sedate.c, function millisec_from_gmtime(),
the last line of the __JSE_WINCE__ section should
be removed. I.E., the following line should
be removed:
JSE_FP_SUB_EQ(diff,JSE_FP_MUL(msPerSecond,\
JSE_FP_MUL(SecondsPerMinute,MinutesPerHour)));
- SE_NUM()
cannot accept negative values
(for ISDK/C 5.00e)
Problem: The manual implies that SE_NUM() can
accept any integer, but it really takes only
positive integers (type sememcount).
- script
functions in shared objects are not locking
all data
(for ISDK/C 5.00e)
Bug: When a script function is being created
as a shared object via seShareReadObject(),
not all of its constants, strings, and varname
are being locked. This may lead to the data
becoming invalid after the garbage collector
runs. The most likely time this bug will become
a problem when a main thread loads a script
and then turns the global into a shared object
so that those script functions can be used by
all threads.
Fix:
moveFunctionToReadShared() in src/core/se500.c,
and localDelete() in src/core/loclfunc.c, should
be replaced by the code found at funclock.txt
- compilation
errors for vxWorks and EPOC min-memory options
(for ISDK/C 5.00e)
Bug: vxWorks and Symbian compiler errors when
using JSE_MIN_MEMORY or the defaults asociated
with JSE_MIN_MEMORY (!JSE_INLINES, SEASSERT_TINY_VERSION).
Fix:
In src/core/seobject.h, at about line 307 (the
first line within the #if JSE_INLINES==0
section) add the following statement:
struct Global_;
next
alter the SEASSERT macros in src/include/sedefopt.h.
Add (void) to the first macro at line 795 so
it reads
# define SEASSERT(condition) ((void)0)
and
for the next SEASSERT macro, at line 798, also
add a (void) so it reads:
# define SEASSERT(condition) \
(void)((condition)?(1):seDbgAssert((int)__ASSERT_FILENO__,(int)__LINE__))
- seInitializeObject()
helper function may not free object reference
(for ISDK/C 5.00e)
Bug: seInitializeObject() will leave an reference
allocated if not called from a wrapper or callback
function.
Fix:
In src/misc/seapiext.c, function seInitializeObject(),
just before the return statement (at about line
620) add this statement:
seFreeObject(se,globalObject);
- dot-named
parse not recognizing dynamic objects
(for ISDK/C 5.00e)
Problem: Our dot-named parser, used in code
such as 'function
foo.goo() { }', was not fully
recognizing dynamic objects in the name, directly
accessing the object's internal members rather
than going through the object's dynamic routines.
Fix:
In src/core/varutil.c, function GetDotNamedVar(),
at about line 1801 this block of code:
# if JSE_DYNAMIC_CALLBACKS!=0
if( SEOBJ_IS_DYNAMIC_PROP(call,hobj,put) )
{
sevarPutValueEx(call,me,varname,tmp2,False);
STACK_POP;
}
# endif
should
be replaces with this code:
# if JSE_DYNAMIC_CALLBACKS!=0
if( SEOBJ_IS_DYNAMIC_PROP(call,hobj,put) )
sevarPutValueEx(call,me,varname,tmp2,False);
else
# endif
next,
find this at about line 1784
else if( (dotFound || FinalMustBeVObject) )
{
seobjGetMember(call,hobj,varname,tmp);
and
replace with
else if( (dotFound || FinalMustBeVObject) )
{
# if JSE_DYNAMIC_CALLBACKS!=0
/* the call to get the member's value was already done in the if-statement
* above.
*/
if( !SEOBJ_IS_DYNAMIC_PROP(call,hobj,get) )
# endif
seobjGetMember(call,hobj,varname,tmp);
lastly, find this line at about line 1764
if( seobjGetMemberSlotNoExpand(call,hobj,varname)==sememcount_NOT_FOUND )
and
replace with this block:
# if JSE_DYNAMIC_CALLBACKS!=0
if( (SEOBJ_IS_DYNAMIC_PROP(call,hobj,get) &&
sevarGetValue(call,me,varname,tmp,SE_DEFAULT)==FALSE) ||
(!SEOBJ_IS_DYNAMIC_PROP(call,hobj,get) &&
seobjGetMemberSlotNoExpand(call,hobj,varname)==sememcount_NOT_FOUND) )
# else
if( seobjGetMemberSlotNoExpand(call,hobj,varname)==sememcount_NOT_FOUND )
# endif
- Number
toExponential() incorrect if fractionDigits
not specified
(for ISDK/C 5.00e)
Bug: Number.prototype.toExponential(fractionDigits)
is treating fractionDigits
as 0
if unspecified. Instead toExponential()
should use as many digits as necessary.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Number_toSomething(),
at about line 1825 a block of code should be
added after f = 0;
as follows:
f = 0;
if ( _toExponential == toWhat )
{
sechar buffer[ECMA_NUMTOSTRING_MAX];
secharptr cptr = (secharptr)buffer;
/* convert using standard tostring rules */
EcmaNumberToString(se,buffer,x);
/* from buffer count how many digits are needed after the decimal,
* that's all digits minus 1
*/
if ( SECHARPTR_GETC(cptr) == '-' ) SECHARPTR_INC(cptr);/* skip any negative */
for ( ; ; )
{
sechar c = SECHARPTR_GETC(cptr);
SECHARPTR_INC(cptr);
if ( '0' <= c && c <= '9' )
f++;
else if ( '.' != c )
break;
}
f--;
}
- Number
toPrecision() incorrect
(for ISDK/C 5.00e) Updated Dec 11, 2002
Bug: Number.prototype.toPrecision(precision)
is converting precision
digits beyond the decimal, when it should be
converting precision-1
digits.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Number_toSomething(),
at about line 1868 the entire toPrecision block
should be replaced with this code:
else
{
senumber abs_x = JSE_FP_FABS(se,x);
SEASSERT( _toPrecision == toWhat );
/* field width must be an int */
/* if x>=pow(10,-6) && x<pow(10,f), use fixed-point notation
* otherwise, use exponential notation */
if( JSE_FP_LTE(JSE_FP_POW(se,JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(-6)),abs_x)
&& JSE_FP_LT(abs_x, JSE_FP_POW(se,JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(f))) )
{
senumber f10 = JSE_FP_LOG10(se,abs_x);
sint d10 = (sint)JSE_FP_CAST_TO_SLONG(f10);
f -= d10;
if ( !jseIsNegative(f10) )
f--;
JSE_FP_DTOSTR(se,x,(int)f,buffer,UNISTR("f"));
}
else
{
JSE_FP_DTOSTR(se,x,(int)f-1,buffer,UNISTR("e"));
}
}
- discrepencies
using delete on global variables
(for ISDK/C 5.00e)
Bug: When delete
is used on global variables that were not created
with the var
keyword, the variables are not being deleted
or the wrong boolean is being returned.
Fix:
In src/core/expressn.c, function secompileOperatorExpression()
under case seTokDelete:,
replace this else block at about line 3011:
else
{
/* not a reference, return 'true', 11.4.1 */
...
}
with
this code:
else if( This->expr.type==EXPR_GLOBAL )
{
secompileAddItem0(This,sePushGlobalObject);
secompileAddItem1(This,seDeleteMember,This->expr.name);
}
else
{
/* not a reference, return 'true', 11.4.1 */
secompileDiscard(This);
secompileAddItem0(This,sePushTrue);
}
Then
in src/core/call.c, callFunction(), find this
comment:
/* no need to set the attributes directly, the variable object
* cannot be referenced by the script, which makes it
* effectively 'DontDelete'.
*/
which
is no longer true. Replace it with:
seobjSetAttributes(call,wLoc->data.ref_val.hBase,
wLoc->data.ref_val.reference,
SE_DONTDELETE);
and
in src/core/varutil.c, function seobjDeleteMember(),
at about line 1846 the case with the comment
/* member doesn't exist; don't delete what does not exist */
should
be changed to return
True;
- non-floating-point
version of sprintf functions using %x or %X
may overwrite memory
(for ISDK/C 5.00e)
Bug: If JSE_FLOATING_POINT is not defined (i.e.
integer only), and %x
or %X
is used in the formatting string of any in any
of the sprintf functions (e.g. se_vsprintf,
sprintf_sechar,
etc...), then memory may be overwritten at the
end of the string buffer.
Fix:
In src/misc/utilstr.c, function se_vsprintf,
in case 'X':
at about line 750 this statement::
strcat_sechar(buf,c);
should
be changed to:
strcpy_sechar(buf,c);
- Blob.put()
loses existing settings for Buffer object
(for ISDK/C 5.00e)
Bug: If Blob.put() is called to alter an exsting
buffer, then a new buffer is created that loses
all non-default information of the old buffer,
such as .unicode or .bigEndian setting, or any
additional properties that have been added to
that buffer object.
Fix:
In src/lib/selib/blobobj.c, add this new function
near the top of the file:
#if defined(JSE_SELIB_BLOB_PUT) || defined(JSE_SELIB_BLOB_SIZE)
static void JSE_NEAR_CALL
replaceSeBufferArg0(secontext se,void *new_data,SE_POINTER_UINDEX new_data_length)
{
struct seMemberDesc mem;
seobject oldb;
seStoreMember(&mem,SE_INDEX(0));
oldb = isBufferType(se,SE_ARGS,&mem)
? seGetObject(se,SE_ARGS,SE_INDEX(0)) : NULL ;
sePutBuffer(se,SE_ARGS,SE_INDEX(0),new_data,new_data_length);
if ( NULL != oldb )
{
seobject newb;
sestring size_str, mem_str;
sememcount objcount, i;
/* copy everything from the old buffer, except size */
size_str = seInternalizeString(se,UNISTR("size"),SE_IS_STRLEN);
newb = seGetObject(se,SE_ARGS,SE_INDEX(0));
objcount = seObjectMemberCountDirect(se,oldb);
for ( i = 0; i < objcount; i++ )
{
sememcount len;
seconstcharptr name;
name = seObjectMemberName(se,oldb,SE_INDEX(i),&len);
mem_str = seInternalizeString(se,name,len);
if ( mem_str != size_str )
{
seAssign(se,newb,SE_STR(mem_str),oldb,SE_INDEX(i));
}
seFreeInternalString(se,mem_str);
}
seFreeInternalString(se,size_str);
}
}
#endif /* #if defined(JSE_SELIB_BLOB_PUT) || defined(JSE_SELIB_BLOB_SIZE) */
and
in both the Blob_put() and Blob_size() functions
replace the calls to
sePutBuffer(se,SE_ARGS,SE_INDEX(0),_ptr_,_len_)
with
replaceSeBufferArg0(se,_ptr_,_len_)
- string
replace, if no matches found, is not returning
the initial string
(for ISDK/C 5.00e)
Bug: If String.prototype.replace() is called
and no replacement is made, then the original
string should be returned.
Fix:
In src/lib/ecma/seobject.c, function string_which_search_helper(),
at about line 3728 is a comment "...could
be no match..." After the seAssignConvert()
call just below that comment this function should
return. With the return
statement that block becomes:
/* could be no match, if replace, return the string from thisVar */
if( seGetType(se,SE_RETURN,SE_VALUE) == SE_TYPE_NULL &&
mode == SE_REPLACE_MODE )
{
seAssignConvert(se,SE_RETURN,SE_VALUE,SE_THIS,SE_VALUE,SE_TOSTRING);
return;
}
- allocation
error in Unicode version of EvalBox demo
(for ISDK/C 5.00e)
Bug: Memory corruption can occur if a string
with newlines is written to the output window
in Unicode versions of the EvalBox demo.
Fix:
In samples/evalbox/evalbox.cpp, at the first
line of WriteToStdOutWindow (about line 456)
sizeof(sechar)
should be multiplied by length, not added to
length. I.E. This line
secharptr text = (secharptr)seGCMalloc(se,sizeof(sechar)\
+(2*strlen_sechar(InitText))+1/*not null*/);
should
be this:
secharptr text = (secharptr)seGCMalloc(se,sizeof(sechar)\
*(2*strlen_sechar(InitText))+1/*not null*/);
- object-members
passed as parameters to functions passed incorrectly
(for ISDK/C 5.00e)
Bug: When a script passes an object member to
a function, the function may receive the wrong
parameter. For example, this code will treat
arguments[0]
incorrectly:
function foo(p1)
{
writeln(arguments[0]);
}
Fix:
In src/core/secode.c, function do_op_member(),
at about line 267 is an if statement following
a comment about "Can't allow 'doubly-indirect'
things...". And else clause should be added
after that if statement so the entire block
becomes this code:
if( !seobjGetChildMember(call,SEVAR_GET_OBJECT(wObjVar),mem,tmp)
|| SEVAR_GET_TYPE(tmp)<VReference )
{
SEVAR_INIT_REFERENCE(wObjVar,SEVAR_GET_OBJECT(wObjVar),mem);
}
else
{
SEVAR_COPY(wObjVar,tmp);
}
- compilation
error if JSE_MUTLIPLE_GLOBAL==1 && JSE_COMPACT_LIBFUNCS==0
(for ISDK/C 5.00e)
Problem: If jseopt.h defines JSE_MULTILE_GLOBAL
but does not define JSE_COMPACT_LIBFUNCS, then
there is a coompilation error.
Fix:
In src/core/util.c, function lib500New(), at
about line 2470 the conditional::
# if JSE_MULTIPLE_GLOBAL==1;
should
be:
# if JSE_MULTIPLE_GLOBAL==1 && JSE_COMPACT_LIBFUNCS==1;
- seEval(..SE_START...)
will grow stack if compilation error
(for ISDK/C 5.00e) Updated January 6, 2003
Problem: If there are compilation errors on
a script in seEval() when using the SE_START
flag, then a value will be left on the VM stack.
If !NDEBUG then an SEASSERT() will be triggered,
otherwise the stack will grow by one value each
time this happens.
Fix:
In src/core/se500.c, near the bottom of function
seEval(), at about line 5991, this line:
if( (flags&SE_START)==0 )
should
be replaced by this line:
if( !ret || (flags&SE_START)==0 )
Note:
This errata item was previously listed with
an inavlid semi-colon at the end of each if
line above. See the errata on that error here:
Typo in seEval() errata
for
5.00d -- (may
apply to earlier version)
- potential
crash with arguments object when receiving many
parameters
(for ISDK/C 5.00d)
Bug: possible memory leak and/or crashes with
arguments object in certain configurations.
Fix:
In src/core/garbage.c, function seobj_new(),
replace this line (at about line 448):
ResizeObjectMembers(call,hobj,wanted);
with
this code
wSEVar tmp = STACK_PUSH;
SEVAR_INIT_NEW_OBJECT(tmp,hobj);
ResizeObjectMembers(call,hobj,wanted);
STACK_POP;
- string.replace
crashes or consumes all memory when replacing
with null string
(for ISDK/C 5.00d)
Bug: When using string.replace() to delete a
character from a string, by replacing it with
"", the call may crash or use too
much memory.
Fix:
In src/lib/ecma/seobject.c, function add_string(),
add this statement as the second line of the
function (at about line 3285):
if ( !add_len ) return;
- sePutXXX()
not returning TRUE as documented
(for ISDK/C 5.00d)
Problem: sePutXXX is often not returning true
on member creation.
Fix:
in src/core/se500.c, function sePutMember(),
locate this section in case SE_STOCK_TYPE:
(at about line is currently (at about line 2734):
if( flags & SE_GF_DIRECT )
{
/* Put the member directly, bypass dynamic calls */
and
just before those lines add this line:
ret = (seobjGetMemberSlot(call,obj,name)==sememcount_NOT_FOUND);
- seGetXXX()
functions ignore dynamic object's hasProp when
retrieving an object value
(for ISDK/C 5.00d)
Problem: seGetXXX ignores a dynamic object's
hasProp when trying to get an object member's
value.
Fix:
in src/core/se500.c, function seGetMember(),
the else
block under case SE_STOCK_TYPE:
is currently (at about line 2232):
wSEVar tmpobj = STACK_PUSH;
SEVAR_INIT_OBJECT(tmpobj,obj);
ret = sevarGetValue(call,tmpobj,name,&(call->save.api_temp),
(flags&SE_GF_DIRECT)?(GV_NO_PROTOTYPE|GV_NO_DYNAMIC):
GV_DEFAULT);
STACK_POP;
but
should be changed to
wSEVar tmpobj = STACK_PUSH;
#if (JSE_DYNAMIC_CALLBACKS==1) && JSE_EXECUTE_SEGMENT==1
ret = TRUE;
SEVAR_INIT_UNDEFINED(tmpobj);
/* If the object says it does not have the property,
* believe it. Return FALSE with the undefined value.
*/
if( (flags&SE_GF_DIRECT)==0 &&
SEOBJ_IS_DYNAMIC_PROP(call,obj,hasProp) )
{
if( seobjCallDynamicProperty(call,obj,SE_HASPROP_CALLBACK,
name,NULL,tmpobj) )
{
ret = (sebool)JSE_FP_CAST_TO_SLONG(SEVAR_GET_NUMBER_VALUE(tmpobj));
if( ret==FALSE )
{
SEVAR_INIT_UNDEFINED(&(call->save.api_temp));
}
}
}
if( ret )
{
#endif
SEVAR_INIT_OBJECT(tmpobj,obj);
ret = sevarGetValue(call,tmpobj,name,&(call->save.api_temp),
(flags&SE_GF_DIRECT)?(GV_NO_PROTOTYPE|GV_NO_DYNAMIC):
GV_DEFAULT);
# if (JSE_DYNAMIC_CALLBACKS==1) && JSE_EXECUTE_SEGMENT==1
}
# endif
STACK_POP;
- JSE_COMPACT_LIBFUNCS
not saving any memory
(for ISDK/C 5.00d)
Problem: Our internal optimization to keep wrapper
functions in a compact form until first accessed
was being undone, causing more memory to be
used than is needed.
Fix:
in src/core/varutil.c, find the function GetDotNamedVar
and look for this line (at about line 1758):
if( !seobjGetMember(call,hobj,varname,tmp) )
change
that to
if( seobjGetMemberSlotNoExpand(call,hobj,varname)==sememcount_NOT_FOUND )
then
find (at about line 1778):
else if( (dotFound || FinalMustBeVObject)
&& SEVAR_GET_TYPE(tmp)!=VObject )
{
and
replace with:
else if( (dotFound || FinalMustBeVObject) )
{
seobjGetMember(call,hobj,varname,tmp);
if( SEVAR_GET_TYPE(tmp)!=VObject )
{
this
will have made the code in the if-block now
inside two if-blocks, so indent that code and
put an extra '}' where the original if-block
ended.
- some
objects made read-only with seShareReadObject()
may never be freed
(for ISDK/C 5.00d)
Problem: Some objects made read-sharable are
not freed.
Fix:
In src/core/se500.c, function moveObjectToReadShared,
remove this block (at about line 6454) so that
only the existing else
block remains:
if( call->Global->all_hobjs==hobj )
{
call->Global->all_hobjs = SEOBJECT_GET(call,hobj,hNext);
}
else
- seGetAttribs
may cause asser error, or return wrong value
(for ISDK/C 5.00d)
Problem: seGetAttribs will not work correctly
under certain circumstances.
Fix:
In src/core/se500.c, function seGetArribs, replace
these lines (at about line 3527):
assert( SEVAR_GET_TYPE(&(call->save.api_temp))==VReference );
slot = seobjGetMemberSlot(call,call->save.api_temp.data.ref_val.hBase,
call->save.api_temp.data.ref_val.reference);
and
replace it with:
if( SEVAR_GET_TYPE(&(call->save.api_temp))==VReference )
{
slot = seobjGetMemberSlot(call,call->save.api_temp.data.ref_val.hBase,
call->save.api_temp.data.ref_val.reference);
}
else
{
assert( SEVAR_GET_TYPE(&(call->save.api_temp))==VReferenceIndex );
slot = (sememcount)call->save.api_temp.data.ref_val.reference;
}
- JSE_COMPACT_LIBFUNCS
may crash while expanding used functions
(for ISDK/C 5.00d)
Problem: Extensive testing shows that in a worst
case, a crash may occur while expanding functions
added with JSE_COMPACT_LIBFUNCS in effect.
Fix:
In src/core/var.c, function seobjGetIndexMember,
find (at about line 533):
# if JSE_COMPACT_LIBFUNCS==1
if( type==VLibFunc )
{
struct seLibFunc libFunc = loc->data.libfunc_val;
/* libfuncexpand must write to member, so free it here first */
libfuncExpand(call,hobj,member,libFunc,type);
}
# else
and
replace it with:
# if JSE_COMPACT_LIBFUNCS==1
if( type==VLibFunc )
{
struct seLibFunc libFunc = loc->data.libfunc_val;
/* libfuncexpand must write to member, so free it here first */
libfuncExpand(call,hobj,member,libFunc,type);
mems = SEOBJECT_GET(call,hobj,hsemembers);
loc = &SEMEMBERS_GET(call,mems,member,value);
}
# else
- seCreateFiber
loses performances gains by reinitializing all
libraries
(for ISDK/C 5.00d)
Problem: seCreateFiber is reinitializing the
function libraries, when they should be shared.
Because it reinitialized them in the same global,
it just overwrote the existing libraries resulting
in a performance decrease to 'redo' already-done
work.
Fix:in
src/core/se500.c, the function seCreateFiber,
find this line (at about line 1130):
call->CallSettings = SE_EXIT_LEVEL|SE_NEW_DEFINES|SE_NO_INHERIT;
and
replace it with:
call->CallSettings = SE_EXIT_LEVEL|SE_NEW_DEFINES|SE_NO_INHERIT|SE_NO_LIBRARIES;
in
src/core/call.c, the function callDelete, find
the first incidence of this block (at about
line this if statement:
if( ((call->CallSettings & SE_NO_INHERIT) &&
!(call->CallSettings & SE_NO_LIBRARIES)) ||
call->prev == NULL )
and
replace with:
if( ((call->CallSettings & SE_NO_INHERIT) &&
!(call->CallSettings & SE_NO_LIBRARIES)) ||
(call->prev==NULL
# if JSE_TASK_SCHEDULER==1
&& fiberSibling==NULL
# endif
) )
- function.protoype.constructor
does not exist for all objects
(for ISDK/C 5.00d)
Problem: Script functions, which may be called
with the new
operator, do not automatically have a prototype.constructor
property, and so object instances created with
new may not inherit a .constructor
property. This auto-constructor behavior is
not part of the ECMAScript standard (according
to our interpretation) but it is described in
most books about ECMAScript and in most browsers.
Fix:
Implementating this behavior, without adversely
affecting performance or memory use, required
too many changes to fit into an errata. The
new code is in the 5.00e release with the SE_AUTO_CONSTRUCTOR
compile-time option.
- seCreateFiber
reinitializes function libraries
(for ISDK/C 5.00d)
Problem: seCreateFiber is reinitializing the
function libraries, when they should be shared.
Because it reinitialized them in the same global,
it just overwrote the existing libraries resulting
in a performance decrease to 'redo' already-done
work.
Fix:
in src/core/se500.c, the function seCreateFiber,
find this line at about 1130:
call->CallSettings = SE_EXIT_LEVEL|SE_NEW_DEFINES|SE_NO_INHERIT;
and
replace with this:
call->CallSettings = SE_EXIT_LEVEL|SE_NEW_DEFINES|SE_NO_INHERIT|SE_NO_LIBRARIES;
and in src/core/call.c, function callDelete(),
at at about line 1906, replace this block:
if( ((call->CallSettings & SE_NO_INHERIT) &&
!(call->CallSettings & SE_NO_LIBRARIES)) ||
call->prev == NULL )
with
this
if( ((call->CallSettings & SE_NO_INHERIT) &&
!(call->CallSettings & SE_NO_LIBRARIES)) ||
(call->prev==NULL
# if JSE_TASK_SCHEDULER==1
&& fiberSibling==NULL
# endif
) )
- Errors
with extremely large Date values
(for ISDK/C 5.00d)
Problem: Date values larger than the maximum
allowable to new Date() can cause nearly-infinite
loops.
Fix:
In src/lib/ecma/sedate.c, function do_date_construction(),
near line 1150 find this block:
else
{
value = seGetNumber(se,SE_ARGS,SE_INDEX(0));
}
and
replace with this:
else
{
value = seGetNumber(se,SE_ARGS,SE_INDEX(0));
value = TimeClip(se,value);
}
- default_this
parameter ignored in seEval(...SE_CONSTRUCTOR...)
(for ISDK/C 5.00d)
Problem: Using the SE_CONSTRUCTOR option of
seEval()ing a function, if you set a default_this
in the params structure, it is ignored.
Fix:
In src/core/se500.c, seEvalFunc(), find this
at about line 5042:
if( flags & SE_CONSTRUCTOR )
{
wSEVar tmp;
sevarInitNewObject(call,this_var,func_var);
and
replace with this:
if( flags & SE_CONSTRUCTOR )
{
wSEVar tmp;
if( params!=NULL && params->default_this!=NULL )
{
SEVAR_INIT_OBJECT(this_var,params->default_this->obj);
}
else
{
sevarInitNewObject(call,this_var,func_var);
}
- during
script compilation peephole optimizer accesses
invalid memory
(for ISDK/C 5.00d)
Problem: The peephole optimizer can access invalid
memory during script compilation. In rare circumstance
this may cause a crash.
Fix:
In src/core/expressn.c, function secompileDelete,
at about line 1240 change this statement:
memmove( sptr, sptr+size, elementMoveCount * sizeof(secodeelem) );
to
memmove( This->opcodes+offsetTo, This->opcodes+offsetFrom,
elementMoveCount * sizeof(secodeelem) );
A
few lines further down, in the function secompilePeephole(),
at about line 1277 add these local variables:
uint i, nxti;
and
then at about line 1287 replace this block
/* The array can move and its size can change, so need
* to recalculate ending point each iteration.
*/
for( sptr = This->opcodes; sptr < (beyond_end = This->opcodes + This->opcodesUsed); )
{
with
this block
/* The array can move and its size can change, so need
* to recalculate ending point each iteration.
*/
for( i = 0; iopcodesUsed; )
{
sptr = This->opcodes + i;
beyond_end = This->opcodes + This->opcodesUsed;
nxti = i+1+SECODE_DATUM_SIZE(*sptr);
and
later in the same function, at about line 1344,
is an secompileDelete statement followed by
a reference to SE_GLOBAL_NOTDIRECTXLAT. Insert
a line between those two statement so it now
reads:
if( !secompileDelete(This,sptr,&targetted,-change) )
break;
sptr = This->opcodes + i;
if ( SE_GLOBAL_NOTDIRECTXLAT <= c )
and
finally, in this same function (at about line
1661) replace this line
sptr = nxt;
with
this line
i = nxti;
- sedbc
bugs with long binary data
(for ISDK/C 5.00d)
Problem: SEDBC can crash when reading from or
writing to database columns representing any
of the large binary data types.
Fix:
In src/lib/sedbc/jse_rfx.c, function jseFieldExchange_LongString(),
case rf_value, at about line 2393 is a call
to SQLBindParameter passing the 8th paramater
as "&value".
That parameter should be "value".
(I.E. value
instead of the address of value.)
And in src/lib/sedbc/obj_oper.c, function LongBinaryToBuffer(),
at about line 118 is a comparison on whether
allocation succeed that is backwards. The line
if( pWritableBuffer )
should
be changed to
if( !pWritableBuffer )
- virtual-stack
growth if retrieving values after an exception
(for ISDK/C 5.00d)
Problem: If an exception is generated during
a call to the SE API, items may be left on the
script stack. This is not likely to cause a
problem in a run-time system, but in debug mode
will cause the SE_API_RETURN() macro to emit
a "stack growth" assertion.
Fix:
In src/core/var.h, in the macros for SEVAR_DEREFERENCE,
are two lines (lines 399 419) like this::
if( !CALL_QUIT(c) ) STACK_POP; \
in
both cases the CALL_QUIT() test should be removed,
so they both become:
STACK_POP; \
- dynamic
get is not being called if hasProp callback
is NULL
(for ISDK/C 5.00d)
Problem: If an object has dynamic callbacks
via seSetCallbacks, but does not implement a
hasProp callback, then the get callback should
be called to determine if the object has the
given property. This is not happening in 5.00d.
Fix:
in src/core/varutil.c, the function seobjHasProperty,
near the top (at about line 2492) is:
if( SEOBJ_IS_DYNAMIC_PROP(call,hobj,hasProp) )
replace
with:
if( SEOBJ_IS_DYNAMIC_PROP(call,hobj,hasProp)
|| SEOBJ_IS_DYNAMIC_PROP(call,hobj,get) )
and then a few lines down (at about line 2500)
immediately after this comment:
/* Make sure that we initialize it in case GC happens */
add these lines:
if( !SEOBJ_IS_DYNAMIC_PROP(call,hobj,hasProp) )
handled = FALSE;
else
- string.split()
incorrect if regular expression used as separator
(for ISDK/C 5.00d)
Bug: String.prototype.split(separator) returns
the wrong results when separator is a regular
expression and does not match the first character
of the string.
Fix:
In src/lib/ecma.c, function Ecma_String_split(),
at about line 2840 (just after the second call
to SplitMatch) this statement:
if( z!=NULL );
should
be changed to:
if( z!=NULL && (!R || seGetLong(se,z,SE_STOCK(index))==0) );
- very
short variable names incorrect if character
> 0x7f
(for ISDK/C 5.00d)
Bug: If a variable name or identifier is 3 characters
or less, and any of the characters is a value
between 0x7f and 0xff (inclusive) (e.g. foo["\xb9"])
it will be converted incorrectly, causing an
assert() or invalid program excecution.
Fix:
In src/core/util.c, in the function CreateVarName,
at about line 393 this statement:
ret |= ((uword32)c) << shift;
should
be changed to:
ret |= ((uword32)(usechar)c) << shift;
- Clib.system()
does not return exit code on Solaris
(for ISDK/C 5.00d)
Problem: Solaris Clib.system doesn't return
exit code of child properly.
Fix:
In src/lib/clib/sestdlib.c, the function Clib_system,
at the end is this block:
# else
sePutNumber(se,SE_RETURN,SE_VALUE,system_sechar(command));
# endif
replace
with:
# else
sePutNumber(se,SE_RETURN,SE_VALUE,system_sechar(command));
# ifdef __sun__
sePutNumber(se,SE_RETURN,SE_VALUE,
WEXITSTATUS(seGetLong(se,SE_RETURN,SE_VALUE)));
# endif
# endif
for
5.00c -- (may
apply to earlier version)
- invalid
getArrayLength() results if no .length member
(for ISDK/C 5.00c)
Problem: On some systems, getArrayLength() returns
2+ billion for the length on objects that do
not have a LENGTH member.
Fix:
src/lib/lang/selngmsc.c, Lang_getArrayLength()
function, find:
maxIndex = max((sememcount)seGetLong(se,obj,SE_STOCK(length)),maxIndex);
and
add before it:
if( seExists(se,obj,SE_STOCK(length)) )
- SElib.interpret()
with no flags turns on all flags
(for ISDK/C 5.00c)
Problem: Not passing the flags argument to SElib.interpret
can turn on all the flags rather than turning
on none.
Fix:
src/lib/selib/selibmsc.c, SELib_interpret function,
at the beginning is:
if( argc > 0 )
flags = seGetInteger(se,SE_ARGS,SE_INDEX(1));
change
that to (just the 0 changed to a 1):
if( argc > 1 )
flags = seGetInteger(se,SE_ARGS,SE_INDEX(1));
- Unix
SElib.directory() function is broken
(for ISDK/C 5.00c)
Problem: Unix SElib.directory() function is
broken.
Fix:
src/lib/selib/sedir.c, AddToDirectoryStructure
function search and find:
sePutObject(se,StrVarArray,SE_INDEX(Total++),elem);
and
replace with:
sePutObject(se,StrVarArray,SE_NUM(Total++),elem);
- On
Unix, some library functions mis-convert NaN
and omitted arguments
(for ISDK/C 5.00c)
Problem: Certain Unix library functions improperly
handle a NaN argument (and an ommited argument).
Fix:in
src/misc/seapiext.h find this line:
#if JSE_FLOATING_POINT==0 || defined(__JSE_PALMOS__)
and
replace with this line:
#if JSE_FLOATING_POINT==0 || defined(__JSE_PALMOS__) || defined(__JSE_UNIX__)
Do
the same in src/misc/seapiext.c right at the
top.
- array.slice(),
string.indexOf(), and string.slice() errors
on Unix and PalmOS
(for ISDK/C 5.00c)
Problem: array.slice(), string.indexOf(), and
string.slice() don't work properly on Unix in
certain cases. This applies to the palm as well.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Array_slice(),
at the top the variables start and end are initialized
via seGetLong. Change both to seGetInteger.
Also, Change the initialization of length from
seGetULong to seGetUInt32.
In
src/lib/ecma/seobject.c, function Ecma_String_indexOf,
the start variable is initialized using seGetLong.
Change that to seGetInteger.
In
src/lib/ecma/seobject.c, find the Ecma_String_slice
function. Replace the initialization references
in start and end from seGetLong to seGetInteger.
- some
unix data parameters can be off
(for ISDK/C 5.00c)
Problem: Some data paramters in unix are off,
especially those referring to DST and offset
from GMT.
Fix:
in src/lib/ecma/sedate.c, function millisec_from_gmtime,
find this #elif block:
# elif defined(__JSE_MAC__) || defined(__JSE_VXWORKS__) \
|| defined(__DEFAULT_TIME_C_FUNCTION__) || defined(__JSE_MAC_MACH_O__)
and
add __JSE_UNIX__ to it like this:
# elif defined(__JSE_MAC__) || defined(__JSE_VXWORKS__) \
|| defined(__DEFAULT_TIME_C_FUNCTION__) || defined(__JSE_MAC_MACH_O__) \
|| defined(__JSE_UNIX__)
- fields
of call structure may not be initialized
(for ISDK/C 5.00c)
Bug: Some fields of the call structure may not
be initialized. Specifically, the useCache boolean
flag is sometimes checked before it is initialized.
This has not been shown to cause any run-time
errors, yet.
Fix:
In src/core/call.c, function callInterpret(),
at about line 1374, add a call to memset() following
the existing call to coreMalloc(), so the code
is now:
call = (struct Call *)coreMalloc(sizeof(struct Call));
if( call==NULL ) return NULL;
memset(call,0,sizeof(struct Call));
- seIsFunc()
error for non-objects
(for ISDK/C 5.00c)
Bug: seIsFunc generates an error if called on
a non-object. It should just return FALSE, i.e.
is not a function.
Fix:
in src/core/se500.c, function seIsFunc(), at
about line 3745, replace this code:
seGetMember(call,object,type,memdata,VObject,SE_DEFAULT);
assert( SEVAR_GET_TYPE(&(call->api_temp))==VObject ||
SEVAR_GET_TYPE(&(call->api_temp))==VUndefined );
with this one line
seGetMember(call,object,type,memdata,VUndefined,SE_DEFAULT);
- seDestroyContext
cannot be called within seEval
(for ISDK/C 5.00c)
Problem: seDestroyContext was written with the
assumption that no seEvals would be currently
executing inside it when called. Since people
want to be able to just abort and cleanup the
context, the function has been changed to support
this.
Fix:
src/core/se500.c, replace the existing seDestroyContext
with this new version:
JSECALLSEQ( void )
seDestroyContext(secontext se)
{
struct Call *call;
sebool again;
assert_is_context( call );
do
{
call = CALL_FROM_JSECONTEXT(se);
again = (call->prev)!=NULL;
callDelete(call);
}
while( again );
}
- crash
with eval() in nested function
(for ISDK/C 5.00c)
Bug: Crash in eval() inside nested function
calls. This bug applies to any wrapper function
trying to call seEval().
Fix:
src/core/call.c, function callCreateVariableObject(),
at about line 1098 find:
while( !FUNCTION_IS_LOCAL(func_orig) || (lookfunc!=NULL && lookfunc!=func_orig) || depth-->0 )
{
and
replace with
while( !FUNCTION_IS_LOCAL(func_orig) || (lookfunc!=NULL && lookfunc!=func_orig) || depth>0 )
{
if( depth ) depth--;
- decodeURI
is missing from standard ECMA libraries
(for ISDK/C 5.00c)
Problem: The standard ECMAScript function "decodeURI"
has been wrongly names "decodedURI".
Fix:
src/lib/ecma/ecmamisc.c at about line 1065 change:
SE_FUNCTION( UNISTR("decodedURI"), Ecma_decodeURI, 1, 1, SE_SECURE, SE_DONTENUM )
to
SE_FUNCTION( UNISTR("decodeURI"), Ecma_decodeURI, 1, 1, SE_SECURE, SE_DONTENUM )
- STACK_INFO
crashes within nested seEval()
(for ISDK/C 5.00c)
Problem: Using STACK_INFO within nested interprets
can crash.
Fix:
src/core/se500.c in the seGetMember function,
find this block at about line 1214:
save = &(init_call->save);
in_prev_call:
and
change it to:
in_prev_call:
save = &(scall->save);
- JSE_MIN_MEMORY
builds truncate SE_SERVICES,SE_VALUE pointer
(for ISDK/C 5.00c)
Problem: Putting a pointer to SE_SERVICES,SE_VALUE
in a min-mem build causes the pointer to be
truncated to 16 bits.
Fix:
There are two places in se500.c where 'GenericData'
is referenced and those require the corrections.
In both cases, the casts should go through the
SE_POINTER_UINT datatype instead of sememcount
since the former is always pointer-sized. The
two changes:
around
line 1831:
SEVAR_INIT_SLONG(&(call->save.api_temp), (SE_POINTER_SINT)(call->Global->GenericData));
and around line 2374:
call->Global->GenericData = (void *)(SE_POINTER_UINT)SEVAR_GET_SLONG(tmp);
- Win32
compilation errors if JSE_WIN_ALL defined
(for ISDK/C 5.00c)
Problem: Win32 builds on se500 with the JSE_WIN_ALL
libraries turned on have compile errors.
Fix:
In
src/lib/win/sent.c line 111, remove the AsmVar
parameter so the line now looks like:
buf = seGetBuffer(se,SE_ARGS,SE_INDEX(0),&CodeLen);
in
src/lib/win/sewin.c line 77 remove one of the
two '0' parameters so the line now looks like:
seSetArray(se,EStuff.var,0);
in
src/lib/win/sewin.c lines 272 and 273 remove
the commas at the end of the lines so they look
like:
SE_INITFUNC(WinLibInitFunction) SE_TERMFUNC(WinLibTermFunction)
- sePutNumber(NaN)
where NaN!=jseNaN are not recognized
(for ISDK/C 5.00c)
Problem: If your code gives the interpreter
any representation of NaN that is not bitwise
identical to jseNaN, then it may not be recognized
as NaN during internal math operations. In debug
builds asserts will be triggered, and in NDEBUG
builds the interpreter may hang.
Fix:
In
src/core/se500.c, function sePutNumberEx(),
at about line 3978, before the call to SEVAR_INIT_NUMBER(),
add this code:
# if JSE_FLOATING_POINT==1
if ( jseIsAnyNaN(val) )
val = jseNaN;
# endif
- #include
statement inserts null-character into source
stream
(for ISDK/C 5.00c)
Problem: When processing the #include
"filespec" directive within
seEval() or sePrecompile(), a null character
will be written at the end of filespec.
This is a problem if the original source is
from SE_TEXT and that original text must not
be overwritten (must be re-used or is in read-only
memory).
Fix:
In
src/core/source.c, function sourceInclude(),
at about line 859 replace this code:
assert( sizeof_sechar(EndQuoteChar) == sizeof_sechar('\0') );
assert( sizeof_sechar('\0') == sizeof(secharptrdatum) );
SECHARPTR_PUTC(End,'\0');
sourceSetPtr(*source,SECHARPTR_NEXT(End));
*source = sourceNewFromFile(call,*source,src,&success);
with
this code:
seconstcharptr filespec = StrCpyMallocLen(src,SECHARPTR_DIFF(End,src));
sourceSetPtr(*source,SECHARPTR_NEXT(End));
*source = sourceNewFromFile(call,*source,filespec,&success);
jseMustFree((void *)filespec);
- errors
with SE_OPT_DEBUGGER
(for ISDK/C 5.00c)
Problem: SE_OPT_DEBUGGER does not work correctly.
Fix:
In
src/core/secode.c, function secodeInterpret()
case seContFunc, at about line 960 find this
line:
if( call->Global->Params.seOptions&SE_OPT_DEBUGGER ) break;
and
change this to:
if( call->Global->Params.seOptions&SE_OPT_DEBUGGER ) return TRUE;
- seEval()
with SE_REPORT_ERRORS is not clearing the error
flag
(for ISDK/C 5.00c)
Bug: seEval() with SE_REPORT_ERRORS not correctly
leaving the context with no error after it is
reported.
Fix:
In src/core/se500.c, at the end of seEval(),
find:
if( flags&SE_REPORT_ERRORS && CALL_ERROR(call) )
CALL_SET_STATE(call,StateNormal);
and
change this to:
if( flags&SE_REPORT_ERRORS && CALL_ERROR(call) )
CALL_SET_NORMAL(call);
- stock
objects passed to seEval with SE_FUNC will not
work
(for ISDK/C 5.00c)
Bug: When calling seEval() with stock objects
and the SE_FUNC flag (e.g. seEval(...,SE_THIS,...,SE_FUNC,...))
the stock object will not be recognized. This
is most likely to show up when the object is
SE_NOWHERE as a result of an invalid call to
seGetObject().
Fix:
In src/core/se500.c, function seEvalFunc(),
add this to the local variable declarations
at the top:
hSEObject realobj = seobjectTohSEObject(call,func_obj);
and
about 20 lines further down in the same function,
just before the statement "pushes += 2;",
replace this line:
SEVAR_INIT_OBJECT(func_var,func_obj->obj);
with this:
SEVAR_INIT_OBJECT(func_var,realobj);
- assert()
or memory leak from seEval(...SE_FUNC..) if
run-time error in script function
(for ISDK/C 5.00c)
Problem: When using seEval() to call a function,
errors in the function could trigger assertions.
In release builds, this would result in a slight
memory leak.
Fix:
In src/core/call.c, function callFunctionFully(),
at about line 139, replace this line:
if( !callMayIContinue(call) )
with
this:
if( !CALL_ERROR(call) && !callMayIContinue(call) )
and 5 lines further down remove the following
3 statements:
wSEVar ret = STACK_PUSH;
SEVAR_INIT_UNDEFINED(ret);
callError(call,textcoreMAYICONTINUE);
- SE_NEW_GLOBALS
flag for seEval() doesn't work
(for ISDK/C 5.00c)
Problem: Specifying a new global in calls to
seEval using the seEval parameters structure
can fail to take effect.
Fix:
In src/core/se500.c, function seEval(), at about
line 5120, replace this line:
HowToInterpret &= ~SE_NEW_GLOBALS;
with
this:
settings &= ~SE_NEW_GLOBALS
- Compilation
errors if JSE_CONDITIONAL_COMPILE not defined
(for ISDK/C 5.00c)
Problem: If jseopt.h does not #define JSE_CONDITIONAL_COMPILE
then there are compilation problems.
Fix:
In src/core/source.c, function sourceNextLine(),
locate the following line at about line 710
and move it to the first line of the function:
sebool firstPass = True;
and
in src/core/security.c, function checkSecurity(),
at about line 68 replace this line:
# if JSE_COMPILER==1
with
this line
# if JSE_COMPILER==1 && JSE_CONDITIONAL_COMPILE==1
for
5.00b -- (may
apply to earlier version)
- Function.prototype.apply()
not accepting null for thisObj parameter
(for ISDK/C 5.00b)
Problem: Function.prototype.apply() should accept
null or undefined as the first parameter, using
the global object for these cases. Instead an
error message is generated.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Function_apply,
at about line 386 replace this conditional:
if( argc > 0 )
with
this:
if( argc > 0
&& SE_TYPE_NULL < seGetType(se,SE_ARGS,SE_INDEX(0)) )
- Documentation
incorrect about lifetime of seGetInternalString()
(for ISDK/C 5.00b)
Problem: The documentation for the function
seGetInternalString(),
states:
The returned pointer is valid as long as
the sestring it is obtained from is valid.
Fix:
That statement is not correct, and should instead
be:
The text represented by many sestring values
is internally stored in a compact format, and
so the string returned by this call may be
stored in a temporary location; the returned
pointer is guaranteed to be valid only until
the next call into the script-engine API.
- If
interpreting very long text lines, // comments
may extend over multiple lines
(for ISDK/C 5.00b)
Problem: If interpreting seEval(...SE_TEXTSE...)
where any line of the raw text string is very
long (usually many hundreds of characters),
and if within the line there is an end-of-line
comments (//),
that comment may wrongly extend until the end
of the buffer.
Fix:
In src/core/code.c, add this function:
static seconstcharptr JSE_NEAR_CALL
endOfSourceLine(seconstcharptr src)
{
sechar c;
do {
SECHARPTR_INC(src);
} while ( (c = SECHARPTR_GETC(src))!=0 && c!='\r' && c!='\n' );
return src;
}
and
in the function tokGetNext() change the three
instance of this line:
goto EndOfSourceLine;
to
this :
status->srcptr = endOfSourceLine(status->srcptr); continue;
- SE_SI_DEPTH
wrong for global code and for first function
(for ISDK/C 5.00b)
Problem: SE_SI_DEPTH was wrong. Outside of any
function ought to be depth 0, in the first function
depth 1, etc. Instead, both outside and the
first function were 0.
Fix:
In src/core/se500.c, function seGetMember(),
within this case block:
case 11: /* SE_SI_DEPTH */
are two instances of the following statment:
if( fptr ) depth++;
Replace
the first such instance, at about line 1296,
replace with this statement:
depth++;
and
remove the second instance, at about line 1305.
- C++
compilation errors in selink.h if JSE_LINK options
is not defined
(for ISDK/C 5.00b)
Problem: If compiling a C++ file, with JSE_LINK
not defined in jseopt.h, the compiler will warn
of mis-matched extern
"C" directives.
Fix:
In src/include/selink.h, at about line 132 add
an extern "C"
this statement just before the definition of
struct jseFuncTable_t,
so those lines are:
# define jseFuncs(CC) (**((struct jseFuncTable_t ** _FAR_ *)CC))
#ifdef __cplusplus
extern "C" {
#endif
struct jseFuncTable_t {
and
around line 116 add another extern "C"
statement before the #endif
so those lines are:
#ifdef __cplusplus
}
#endif
#endif /* #if JSE_LINK==1 || defined(JSETOOLKIT_LINK) */
- string
slice() function is not accepting zero parameters
(for ISDK/C 5.00b)
Problem: String.prototype.slice() will report
an error if it is passed no parameters. Instead,
it should treat calls to string.slice()
as string.slice(0).
Fix:
In src/lib/ecma/seobject.c, at about line 3760,
change this line:
SE_METHOD( UNISTR("slice"), Ecma_String_slice,1,2,SE_SECURE,SE_DONTENUM)
to
this
SE_METHOD( UNISTR("slice"), Ecma_String_slice,0,2,SE_SECURE,SE_DONTENUM)
- seEval(...SE_FUNC...)
does not generate exception if object is not
a function
(for ISDK/C 5.00b)
Problem: Calling seEval() with a function (the
SE_FUNC flag) will return False but will not
generate an exception and will not call the
seAttErrorFunc or sePrintErrorFunc. Instead,
this will call the internal API function. In
other words, calling seEval() with an invalid
function object is viewed as an API error instead
of a scripting error.
Fix:
The underlying API philosophy is the seEval()
should behave much like the script eval() function,
and so using a non-function object as an API
error is wrong. In src/core/se500.c, function
seEvalFunc(), at about line 4172 changine this
line:
seAPIError(call,UNISTR("Object passed as a function to seEval is not really a function."));
to
this
callQuit(call,textcoreNOT_FUNCTION_VARIABLE,UNISTR(""));
- 5-character
variables names incorrect if either of last
two characters is '$'
(for ISDK/C 5.00b)
Bug: In many cases, internal representation
of variable names will be incorrect if the string
is 4 or 5 characters long and either of the
last two characters are '$'. For example, the
names "book" and "book$"
would conflict and both represent the same variable.
Fix:
In srcore/util.c, function CreateVarName(),
at about line 349 (following the test for '$' == c,
change this line:
if( i==4 )
to
this
if( i==5 )
for
5.00a --
- String
replace may skip matches if replacement string
is null-string (i.e. "")
(for ISDK/C 5.00a)
Bug: If the replacement expression in a string
replace() method is the zero-length string,
then characters may be skipped in performing
the replacement. For example, this script would
fail the test:
var str = '6 abcdef';
var rtn = str.replace(/[^0-9\.]/g,'');
Test.assert( rtn == "6" ); // in error would be "6acf"
Fix:
In srclib/ecma/seobject.c, function string_search_helper(),
replace the block of code beginning with "/* The return from exec should be an object"
with the code found at ftp://ftp.nombas.com/pub/isdkeval/se500/string_search_helper.txt
- rare
crashes on memory overwrites using the dynamicBuffer
routines
(for ISDK/C 5.00a)
Bug: Code may overwrite one byte beyond allocated
memory when using the dynamicbuffer functions.
Fix:
In src/lib/common/selibutl.c, function dynamicBufferAppendLength(),
at about line 142 change this line:
} while( buf->used + length > buf->allocated );
to
this:
} while( buf->used + length >= buf->allocated );
- Problems
with array lengths and numeric indices that
are large or non-integer
(for ISDK/C 5.00a)
Bug: There are many problems with handling array
and object members that are either very large
(e.g. obj[2147483650])
or are non-integer numbers (e.g. obj[3.14159],
obj[1e34]).
There are also related problems with setting
an array length to a very large number (e.g.
array.length=2147483650).
Fix:
The number of changes needed to fix these problems
in such a way that they would work on all build
types (fp, fpemul, nofp) without a loss of performance
was very large. Because the number of changes
was so large we recommend that you update to
version 5.00b.
- Foo.prototype.constructor
not assigned correctly for all builtin objects
(for ISDK/C 5.00a)
Bug: For all builtin objects, this statement
should be true: Foo.prototype.constructor==Foo.
For example Boolean.prototype.constructor==Boolean
and Number.prototype.constructor==Number.
Fix:
Version 5.00b defines SE_CLASS() differently,
so that these relationships are created automatically.
In version 5.00a the behavior is in almost all
respects identical to the defined behavior,
and so this code does not need changing. If
you must get this exact behavior in 5.00a then
in src/lib/ecma/*.c locate all of the lines
like this (where instead of "Foo"
find "Number", and "String",
etc...):
SE_METHOD( JseStr(NULL,constructor), Ecma_Foo_builtin, 0, 0, SE_SECURE, SE_DONTENUM )
delete
those lines, and instead add after the enclosing
SE_END_CLASS statement:
SE_COPY( UNISTR("Foo.prototype.constructor"), UNISTR("Foo"), SE_DONTENUM )
- Array
split() error for negative starting point
(for ISDK/C 5.00a)
Bug: Array split() is not handling negative
start values correctly. This error shows up
in different ways with different compilers,
but the following example would fail on all
systems:
var a = [1,2,3,4,5,6];
var b = a.splice(-100,1);
Test.assert( a == "2,3,4,5,6" ); // wrongly returns "1,2,3,4,5"
Test.assert( b == "1" ); // wrongly returns ""
Fix:
In src/lib/ecma/seobject.c, function Ecma_Array_splice(),
at about line 1179 change the code from:
start = (slong) max( length + start, 0 );
to
start = (slong) max( (slong)length + start, 0 );
- Math.min(+0,-0)
wrongly returns +0
(for ISDK/C 5.00a)
Bug: Math.min() is not returning -0 when comparing
-0 against +0.
Fix:
In src/lib/ecma/mathobj.c, function Ecma_Math_min(),
at about line 390 change the comparison from:
if( JSE_FP_LT(current,minval) )
to
if( JSE_FP_LT(current,minval) || ( jseIsNegZero(current) && jseIsZero(minval) ) )
- Clib.localtime()
and Clib.gmtime() crash on out-of-range dates
(for ISDK/C 5.00a)
Bug: Script calls to Clib.localtime() or Clib.gmtime()
crash if the input time is out of the range
of standard C library time routines.
Fix:
In src/lib/clib/setime.c, function GenericTimeLib(),
at about line 304 just after any of the ConversionFunc
functions will have been called, insert this
code:
if ( t == NULL )
{
sePutNull(se,SE_RETURN,SE_VALUE);
return;
}
- Number
toString(with_radix) method is not handling
NaN, Infinity, and -Infinity
(for ISDK/C 5.00a)
Bug: Converting an instance of a Number object
toString, using a radix (e.g. (new Number(foo)).toString(16);)
does not produce correct results if the number
is NaN, Infinity, or -Infinity.
Fix:
In src/lib/ecma/seobject.c, function Ecma_Number_toString(),
at about line 1709 cahnge the JSE_NUMBER_TO_STRINGWITHRADIX
code to be this:
if ( 0 < argc )
{
slong radix = seGetLong(se,SE_ARGS,SE_INDEX(0));
if ( radix==10 || !jseIsFinite(num) )
EcmaNumberToString(se,buffer,num);
else
EcmaNumberToStringWithRadix(se,num,(sint)radix,buffer);
}
else
- Invalid
date computation on negative month
(for ISDK/C 5.00a)
Bug: Date calculations are incorrect, and can
trigger debugger asserts, if month is negative.
For example, the following script should set
the month to October (month 9) and year to 1980,
but instead it sets the month to January (month
0) and year to 1981.
var foo = new Date("12:00 February 4, 1982");
foo.setUTCMonth(-15);
Fix:
In src/lib/ecma/sedate.c, function MakeDay(),
insert code between lines 640 and 642 add code
so those lines become:
r6 = m%12;
if ( r6 < 0 )
{
r6 += 12;
r5--;
}
t = TimeFromYear(se,r5);
- When
named parameters are disabled, calling a function
with seEval() fails
(for ISDK/C 5.00a)
Bug: If JSE_NAMED_PARAMS
(named paramters) is not enabled in your jseopt.h
file, then calling a function with seEval()
will fail.
Fix:
In src/core/se500.c, function seEvalFunc(),
at line 4171 alter the code from:
if( args!=NULL )
{
# if JSE_NAMED_PARAMS==1
if( (flags & SE_NAMED_PARAMS)==0 )
{
to
if( args!=NULL )
{
# if JSE_NAMED_PARAMS==1
if( (flags & SE_NAMED_PARAMS)==0 )
# endif
{
and
at about 4213 change from
}
else
# endif /* #if JSE_NAMED_PARAMS==1 */
{
wSEVar onstack;
to
}
# if JSE_NAMED_PARAMS==1
else
{
wSEVar onstack;
and
finally at about line 4239 change from
onstack = STACK_PUSH;
SEVAR_INIT_OBJECT(onstack,args);
}
}
to
onstack = STACK_PUSH;
SEVAR_INIT_OBJECT(onstack,args);
}
# endif
}
- argv[0]
is missing
(for ISDK/C 5.00a)
Bug: When building with the JSE_MAIN_ARGC_ARGV
option, argv[0] is supposed to be the script
name, but argv[0] is missing.
Fix:
Many changes were needed to correct this. These
changes will be released shortly with version
5.00b
- Math.round()
returns -0 instead of +0 from -0.5 to -0
(for ISDK/C 5.00a)
Bug: Math.round(val) should return -0 for -0.5
<= val <= -0, according to section 15.8.2.15
of the ECMAScript specification, but is returning
+0.
Fix:
In src/lib/ecma/mathobj.c, function Ecma_Math_round,
the "if"
statement and block should be changed to:
if ( jseIsFinite(val) && !jseIsZero(val) )
{
senumber half = JSE_FP_DIV(jseOne,JSE_FP_CAST_FROM_SLONG(2));
/* exception to standard math if between -0.5 and -0, inclusive */
if ( JSE_FP_LT(val,jseZero) && JSE_FP_LTE(JSE_FP_NEGATE(half),val) )
val = jseNegZero;
else
val = JSE_FP_FLOOR(se,JSE_FP_ADD(val,half));
}
- properties
of the arguments object should be DontEnum
(for ISDK/C 5.00a)
Bug: callee, length, and numbered members of
the arguments object are enumerable, should
be DontEnum.
Fix:
In src/core/call.c, function callCreateArguments(),
replace this statement:
seobjCreateMemberCopy(call,hArgs,STOCK_STRING(call,callee),tmp,SE_DEFAULT);
with
this:
seobjCreateMemberCopy(call,hArgs,STOCK_STRING(call,callee),tmp,SE_DONTENUM);
and
replace three instances of this statement:
mems->attributes = SE_DEFAULT;
with
this:
mems->attributes = SE_DONTENUM;
- post-inc/decrement
operator acts like pre-inc/decrement inside
a "with" block
(for ISDK/C 5.00a)
Bug: If a variable member of an object is altered
with the post-increment or pre-decrement operator,
and if that is a member of an object scoped
with "with", then the code will instead
act like a pre-increment or pre-decrement operator.
Fix:
In src/core/secode.c, function secodeInterpret(),
find the switch case started with:
case sePostDecLocalWith:
case sePostIncLocalWith:
case sePreDecLocalWith:
case sePreIncLocalWith:
{
at
the end of that block is this line:
DO_CREMENT(w_rhs,w_lhs,(jsebool)(t&1),t<=sePreDecLocal)
change
the sePreDecLocal to sePreDecLocalWith so it
reads:
DO_CREMENT(w_rhs,w_lhs,(jsebool)(t&1),t<=sePreDecLocalWith)
- post-increment
operator on local variable is ignoring "with"
statement
(for ISDK/C 5.00a)
Bug: If a local variable is also a member of
the current "with" object, then post-increment
will modify the local variable instead of the
variable in the "with" object. For
example, the following would wrong increment
"foo" and not "myobj.foo"
function blah()
{
var foo = 14;
var myobj = new Object();
myobj.foo = 88;
with ( myobj )
{
foo++;
}
Fix:
In srccore/expressn.c, function secompilePostfixExpression(),
change the EXPR_LOCAL case (approx line 2445):
secompileAddItem2(this,sePostIncLocal+inc,this->expr.index,this->with_depth);
to
be these lines:
if ( This->with_depth )
secompileAddItem2(This,sePostIncLocalWith+inc,This->expr.index,This->with_depth);
else
secompileAddItem1(This,sePostIncLocal+inc,This->expr.index);
|