Nombas Homepage

Scripting

Products

Purchase

Download

Support

Company

Nombas > SE:ISDK DevSpace > Errata > Integration SDK 5.00x Errata

 

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
  • 5.00e API - latest update: February 14, 2003
  • 5.00d API - latest update: November 13, 2002

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,&params);

to:

   ret = seEval(se,func,SE_FUNC,NULL,stack,SE_DEFAULT,&params);

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);
   

Home | Scripting | Products | Purchase | Download | Support | Company

Copyright ©2001, Nombas, Inc. All Rights Reserved.
Questions? Visit
http://support.nombas.com/