Nombas Homepage

Scripting

Products

Purchase

Download

Support

Company

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

 

Integration SDK 4.40x Errata
Fixes Affecting Users of the ScriptEase ISDKs

  • 4.40f API - latest update: September 9, 2004
  • 4.40e API - latest update: January 28, 2003

API Errata, version 4.40f (may apply to earlier versions)
  New, September 9, 2004

API Errata, version 4.40e (may apply to earlier versions)
  New, January 28, 2003

API Errata, version 4.40d (may apply to earlier versions)
  New, March 7, 2002

API Errata, version 4.40c (may apply to earlier versions)
  New, October 6, 2001

The Details

for 4.40f -- (may apply to earlier versions)

  • COM object methods returning an array may cause an assertion
    (for ISDK/C 5.01b)

Bug: Calling a method of a COM object that returns an array may cause an assertion around line 803 in src/lib/comobj/comobj.cpp, function CreateReturnedVariant().

Fix : In se501/src/lib/comobj/comobj.cpp, around line 865, there is an else statement containing a for loop that looks like this:

      for( i = lowerBound; i <= upperBound; i++ )
      {
         VARIANT v;
         jseVariable mem = jseIndexMemberEx(jsecontext,jseRet,i,jseTypeUndefined,jseCreateVar);
         indicies[dim] = i;
         /* Get the element from the safe array */
         /* I'm making an assumption here, which is the elements of the
          * array will be VARIANTS.
          */
         hr = SafeArrayGetElement(psa,indicies,&v);

         if(FAILED(hr))
         {
            ReportComError( jsecontext, hr, &excepInfo );
         }

         jseVariable tmp = CreateReturnedVariant(jsecontext,v,wName);
         jseAssign(jsecontext,mem,tmp);
         jseDestroyVariable(jsecontext,mem);
         jseDestroyVariable(jsecontext,tmp);

      }

Replace that entire for loop with this one:

      for( i = lowerBound; i <= upperBound; i++ )
      {
         VARIANT v;
         VARTYPE vt;
         VariantInit(&v);
         indicies[dim] = i;
         jseVariable mem = jseIndexMemberEx(jsecontext,jseRet,i,jseTypeUndefined,jseCreateVar);
         /* Get the element from the safe array */
         /* I'm making an assumption here, which is the elements of the
          * array will be VARIANTS.
          */
         hr = SafeArrayGetVartype(psa, &vt);

         if(FAILED(hr))
         {
            ReportComError( jsecontext, hr, &excepInfo );
         }

         V_VT(&v) = vt;

         switch (vt) /* default to original assumption of variant */
         {
            case VT_BOOL:
               hr = SafeArrayGetElement(psa,indicies,&(V_BOOL(&v)));
               break;
            case VT_BSTR:
               hr = SafeArrayGetElement(psa,indicies,&(V_BSTR(&v)));
               break;
            case VT_I4:
               hr = SafeArrayGetElement(psa,indicies,&(V_I4(&v)));
               break;
            case VT_UI4:
               hr = SafeArrayGetElement(psa,indicies,&(V_UI4(&v)));
               break;
            case VT_UI2:
               hr = SafeArrayGetElement(psa,indicies,&(V_UI2(&v)));
               break;
            case VT_I2:
               hr = SafeArrayGetElement(psa,indicies,&(V_I2(&v)));
               break;
            case VT_I1:
               hr = SafeArrayGetElement(psa,indicies,&(V_I1(&v)));
               break;
            case VT_UI1:
               hr = SafeArrayGetElement(psa,indicies,&(V_UI1(&v)));
               break;
            case VT_R4:
               hr = SafeArrayGetElement(psa,indicies,&(V_R4(&v)));
               break;
            case VT_R8:
               hr = SafeArrayGetElement(psa,indicies,&(V_R8(&v)));
               break;
            case VT_DECIMAL:
               hr = SafeArrayGetElement(psa,indicies,&(V_DECIMAL(&v)));
               break;
            case VT_DATE:
               hr = SafeArrayGetElement(psa,indicies,&(V_DATE(&v)));
               break;
            default:
               hr = SafeArrayGetElement(psa,indicies,&v);
         }

         if(FAILED(hr))
         {
            ReportComError( jsecontext, hr, &excepInfo );
         }

         jseVariable tmp = CreateReturnedVariant(jsecontext,v,wName);
         jseAssign(jsecontext,mem,tmp);
         jseDestroyVariable(jsecontext,mem);
         jseDestroyVariable(jsecontext,tmp);
      }

  • comobj returning variables passed by reference in reverse order
    (for ISDK/C 4.40f)

Bug: Method arguments passed to a COM object's method by reference (according to the declaration of the COM object's method) are returned in the reverse order of how they went in.

Fix: In srclib/comobj/comobj.cpp, function oleGenericDispatcher(), there is a comment that starts with "Since we are now allowing pass by reference". About nine lines below the beginning of that comment, there is a line that looks like this:

   jseVariable oldVar = jseFuncVar(jsecontext,i);
                                

Replace that line with this one:

   jseVariable oldVar = jseFuncVar(jsecontext,args-i-1);
                                

  • function parsing errors can cause memory corruption
    (for ISDK/C 4.40f)

Bug: If the engine encounters an erroroneous situation while parsing a function definition, it can cause the engine to try to deallocate a block of memory associated with the internal representation of that function twice.

Fix: In srccore/expressn.c, function secompileFunction(), there is an if statement like this:

   if( tokType(token)!=seTokIdentifier )
                                

Below that if statement there is a block of code that looks like this:

   ...
   localDelete(call,newfunc);
   return False;
                                

Replace those two lines with the following block of code:


   /* Remove the function from the global function chain, to make sure it does not get
    * freed again.
    */

   assert( call->Global->funcs == &(newfunc->function) );
   call->Global->funcs = (newfunc->function.next);
            
   localDelete(call,newfunc);
   jseMustFree(newfunc);
   return False;
                                

  • previous String match errata broke String replace
    (for ISDK/C 4.40f)

Bug: A previous errata (see below) fixed a problem with string.match() but introduced a new problem in string.search(). The new bug is that string.search(), if no match is found and if the global flag is used, will return null instead of returning the original string.

Fix: In srclib/ecma/seobject.c, function string_search_helper(), at about line 4750, the code just before the comment beginning with "/* I hate destroying the stack" which was introduced in the string.match errata, should change from this:

   #if 1
   /* this part of the code is a result of the ECMA-262 errata */
   jseDestroyVariable(jsecontext,ret);
   ret = jseCreateVariable(jsecontext,jseTypeNull);
   #endif;

to this:

   #if defined(JSE_STRING_REPLACE)
   if ( mode != JSE_REPLACE )
   #endif
   {
      /* this part of the code is a result of the ECMA-262 errata */
      jseDestroyVariable(jsecontext,ret);
      ret = jseCreateVariable(jsecontext,jseTypeNull);
   }

  • string.concat() fails when strings are zero-length
    (for ISDK/C 4.40f)

Bug: If the strings in string.concat() are all zero-length, then a memory allocation failure is reported.

Fix: In srclib/ecma/seobject.c, function Ecma_String_concat(), att "+1" to this line (around line 4032):

   BYTECOUNT_FROM_STRLEN(result,length)+BYTECOUNT_FROM_STRLEN(str,strlength));

to this:

   BYTECOUNT_FROM_STRLEN(result,length)+BYTECOUNT_FROM_STRLEN(str,strlength)+1);

  • Math.random() is not very random on systems with 16-bit integers
    (for ISDK/C 4.40f)

Bug: On systems compiled with 16-bit integers, Math.random() always generates numbers very close to 0.0 or 1.0 (e.g. 0.0545345 or 0.992322), and not well-spread between 0 and 1.

Fix: In srclib/ecma/mathobj.c, function Ecma_Math_random(), change this line:

   int r[5];

to this:

   uword32 r[5];

  • Date parser not recognizing 12 AM or "UTC"
    (for ISDK/C 4.40f)

Problem: When parsing a date/time with "12:00 AM UTC" the date parser is not recognizing this as midnight, but is instead registering that time as noon. Also, although the ECMAScript specification sets "GMT" as the tag for declaring universal time, it has become common to also use "UTC".

Change: In srclib/ecma/sedate.c, function do_parse(), at around line 791, just before the comment that begins "/* if there is a PM anywhere..." add this code:

   /* if it is 12, but 12 AM, then that time is really 0 */
   if ( time[0] == 12  &&  strstr_jsechar(DateBuf,UNISTR("am")) )
      time[0] = 0;

and then at about line 974 change this code

   gmt = strstr_jsechar(DateBuf,UNISTR("gmt"));
   if ( gmt == NULL )

to this

   if ( NULL == (gmt = strstr_jsechar(DateBuf,UNISTR("gmt")))
     && NULL == (gmt = strstr_jsechar(DateBuf,UNISTR("utc"))) )

  • String match function should return null on no match
    (for ISDK/C 4.40f)

Issue: According to the commonly recognized ECMAScript Edition 3 Errata, string.match should return NULL if there are no items matched. This differs from the ECMAScript document, and from our 4.40f code, which would return a zero-length array. Note: This errata introduced a string.search() bug as described above.

Change: To get the return-null behavior, In srclib/ecma/seobject.c, near the end of string_search_helper() (at about line 4750) replace this code:

   /* I hate destroying the stack in multiple places, but the
    * 'func_ret' will go away with the stack, so the stack
    * has to remain as long as accessing it.
    */
   jseDestroyStack(jsecontext,stack);
   break;

with

   #if 1
   /* this part of the code is a result of the ECMA-262 errata */
   jseDestroyVariable(jsecontext,ret);
   ret = jseCreateVariable(jsecontext,jseTypeNull);
   #endif
   /* I hate destroying the stack in multiple places, but the
    * 'func_ret' will go away with the stack, so the stack
    * has to remain as long as accessing it.
    */
   jseDestroyStack(jsecontext,stack);
   break;

  • recursive MARK_OBJECT alternative (eliminating MARK_STACK_SIZE) frees in-use destructors
    (for ISDK/C 4.40f)

Bug: The FAQ code describing how to replaces MARK_STACK_SIZE problems (see below) with a recursize version (similar to what is found in 5.01) has a bug that frees destructor objects before they are called--this can crash. That FAQ is found at segmentation fault during GC with small MARK_STACK_SIZE on solaris

Fix: That FAQ (segmentation fault during GC with small MARK_STACK_SIZE on solaris). The new code is this block added at the end:

   if( global->destructorCount )
   {
      uint i;
      for( i=0; i < destructorCount; i++ )
         MARK_OBJECT(global->hDestructors[i],&mstackinfo);
   }

  • memory leak with array.toSource
    (for ISDK/C 4.40f)

Bug: A memory buffer remains unreleased for each call to Array.prototype.toSource. This would happen any time ToSource is applied to an instance of an Array, or to any object containing an instance of an Array.

Fix: In src/lib/ecma/seobject.c, function Ecma_Array_toSource, the following should be added as the last line of the function at about line 1805:

   jseDestroyVariable(jsecontext,ret);

  • Alignment errors with Clib *printf and *scanf floating-point on HP-UX
    (for ISDK/C 4.40f)

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 srclib/clib/sefmtio.c with the file at ftp://ftp.nombas.com/pub/isdkeval/se440/sefmtio.c

  • system can become corrupted if number of objects in use is greater than MARK_STACK_SIZE
    (for ISDK/C 4.40f)

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 srccore/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;
   
      VarName vn = SEMEMBERS_GET(basecall,mems,i,name);
      if( NO_VARNAME != vn
       && IsNormalStringTableEntry(vn)
       && 0 == (HashListFromVarName(vn)->locks & JSE_STRING_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 4.40f)

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 955, this statement:

   if ( NULL == (decimal=strchr_jsechar((jsecharptr)buffer,'.')) )

should become:

   if ( NULL == (decimal=strchr_jsechar((jsecharptr)buffer,'.'))
     && NULL == (decimal=strchr_jsechar((jsecharptr)buffer,',')) )

  • Memory corruption on %s error messages
    (for ISDK/C 4.40f)

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 jseLibErrorPrintf() calls but are not limiting the length of string arguments.

Fix: Edit the files srccore/rsrccore.h and srclib/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 jse_vsprintf in srcmisc/utilstr.c (if your system does not supply a native implementation of vsprintf) then contact http://support.nombas.com/ for a replacement function.

  • SElib.dynamicLink() expects string lengths to remain constant
    (for ISDK/C 4.40f)

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 srclib/common/sedyna.c, function CallDynamicFunction(), at about line 217 change the statement from:

   jsePutStringLength(jsecontext,v,(jsecharptr )data,BufferLengths[i]);

to:

   jsePutString(jsecontext,v,(jsecharptr )data);

  • bad error message, or crash, when "goto" statement is not followed by a label
    (for ISDK/C 4.40f)

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 srccore/statemnt.c, function secompileStatement(), in the "case seTokGoto:" change line 974 from:

   callQuit(this->call,textcoreGOTO_LABEL_NOT_FOUND);

to:

   callQuit(this->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 465, 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.

  • COMOBJ leaks resources
    (for ISDK/C 4.40f)

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 srclib/comobj/* code with files found at ftp://ftp.nombas.com/pub/isdkeval/se440/comobj_2003_03_20.zip


for 4.40e -- (may apply to earlier versions)

  • comobj times miscalculate DST
    (for ISDK/C 4.40e)

Bug: In converting times between a script and a COM object, the daylight-savings time calculation may be off by one hour.

Fix: In srclib/comobj/comobj.cpp, function UnixTimeToSystemTime() replace the body of that function (at about line 210) with this code:

   struct tm * localUnixTime = localtime(&t);
   pst->wYear = (localUnixTime->tm_year + 1900);
   pst->wMonth = localUnixTime->tm_mon+1;
   pst->wDayOfWeek = localUnixTime->tm_wday;
   pst->wDay = localUnixTime->tm_mday;
   pst->wHour = localUnixTime->tm_hour;
   pst->wMinute = localUnixTime->tm_min;
   pst->wSecond = localUnixTime->tm_sec;

then in function CreateReturnedVariant() replace this line (at about line 631):

   time_t t = SystemTimeToUnixTime(&st);

with this block:

   time_t t;
   struct tm gm;
   
   /* Construct a tm structure based on the SYSTEMTIME structure */
   gm.tm_year = (st.wYear - 1900);
   gm.tm_mon = st.wMonth-1;
   gm.tm_wday = st.wDayOfWeek;
   gm.tm_mday = st.wDay;
   gm.tm_hour = st.wHour;
   gm.tm_min = st.wMinute;
   gm.tm_sec = st.wSecond;
   gm.tm_isdst = -1;
   
   /* Get the time_t */
   t = mktime(&gm);

  • function.protoype.constructor does not exist for all objects
    (for ISDK/C 4.40e)

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 many changes. For details about implementing this change in 4.40e see this tech-support item: Title: comparing object.constructor to its constructor function fails

  • stack corruption with long mode parameter to Clib.fopen() and Clib.freopen()
    (for ISDK/C 4.40e)

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 srclib/sestdio.c, functions Clib_fopen() and Clib.freopen() change this line (at about line 634 and 705)

   strcpy_jsechar((jsecharptr)NewMode,Mode);

to this

   memset(NewMode,0,sizeof(NewMode));
   strncpy_jsechar((jsecharptr)NewMode,Mode,sizeof(NewMode)/sizeof(NewMode[0])-2);

  • array sort return invalid when array.length==1
    (for ISDK/C 4.40e)

Bug: If array.length==1, then array.sort() will return undefined.

Fix: In srclib/ecma/seobject.c, function Ecma_Array_sort(), the code (near line 1094) for "<=1" elements should be changed to:

   if( num_items <= 1 )
   {
      jseReturnVar(jsecontext,thisvar,jseRetCopyToTempVar);
      return;
   }

  • Number toExponential() incorrect if fractionDigits not specified
    (for ISDK/C 4.40e)

Issues: 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 2274 a block of code should be added after f = 0; as follows:

   f = 0;
   if ( _toExponential == toWhat )
   {
      jsechar buffer[ECMA_NUMTOSTRING_MAX];
      jsecharptr cptr = (jsecharptr)buffer;
      /* convert using standard tostring rules */
      EcmaNumberToString(jsecontext,buffer,x);           
      /* from buffer count how many digits are needed after the decimal, that's all digits minus 1 */
      if ( JSECHARPTR_GETC(cptr) == '-' ) JSECHARPTR_INC(cptr);/* skip any negative */
      for ( ; ; )
      {
         jsechar c = JSECHARPTR_GETC(cptr);
         JSECHARPTR_INC(cptr);
         if ( '0' <= c  && c <= '9' )
            f++;
         else if ( '.' != c )
            break;
      }
      f--;
   }

  • Number toPrecision() incorrect
    (for ISDK/C 4.40e) Updated Dec 11, 2002

Issues: Number.prototype.toPrecision(precision) is converting precision digits beyond the decimal, when it should be converting precision-1 digits.

Fix: In srclib/ecma/seobject.c, function Ecma_Number_toSomething(), at about line 2319 the entire toPrecision block should be replaced with this code:

   else
   {
      jsenumber abs_x = JSE_FP_FABS(se,x);
   
      assert( _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(jsecontext,JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(-6)),abs_x) &&
          JSE_FP_LT(abs_x, JSE_FP_POW(jsecontext,JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(f))) )
      {
         jsenumber 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(jsecontext,x,(int)f,buffer,UNISTR("f"));
      }
      else
      {
         JSE_FP_DTOSTR(jsecontext,x,(int)f-1,buffer,UNISTR("e"));
      }
   }

  • jsePutString() may overwrite previous results if JSE_C_EXTENSIONS is disabled
    (for ISDK/C 4.40e)

Bug: If compiling with JSE_C_EXTENSIONS 0, then when jsePutString() or similar calls are used to assign to a variable (especially via dynamic callbacsk as in the RegExp global object), existing string data may be overwritten.

Fix: In srccore/jselib.c, function GenericPutDataPtr(), at about line 2034 this block of code:

      if( SEVAR_GET_TYPE(val)==VString && (SESTR_IS_CONSTANT(SEVAR_GET_STRING(val).data)
   #     if JSE_C_EXTENSIONS==1
                                           ||  !callLocalCBehavior(call)
   #     endif
                                           ) )

should be replaced with this code

      if( SEVAR_GET_TYPE(val)==VString
   #   if JSE_C_EXTENSIONS==1
       && (SESTR_IS_CONSTANT(SEVAR_GET_STRING(val).data) || !callLocalCBehavior(call))
   #   endif
        )

  • unknown preprocessor directive, if very long, crashes
    (for ISDK/C 4.40e)

Bug: If a preprocessor directive is very long (e.g. #OIJOJOIJOIQJOIJEWOJWOEOIJOIJ...) then a crash may occur while preparing an error message.

Fix: In srccore/util.c, function PreprocessorDirective(), at about line 2239 replace this line

   callError(call,textcoreUNRECOGNIZED_PREPROCESSOR_DIRECTIVE,src);

with this block:

   {
      jsechar buf[41];
      memset(buf,0,sizeof(buf));
      strncpy_jsechar((jsecharptr)buf,src,sizeof(buf)/sizeof(buf[0])-1);
      callError(call,textcoreUNRECOGNIZED_PREPROCESSOR_DIRECTIVE,buf);
   }

  • string.replace crashes or consumes all memory when replacing with null string
    (for ISDK/C 4.40e)

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 srclib/ecma/seobject.c, function add_string(), add this statement as the first line of the function (at about line 4200):

   if ( !add_len ) return;

  • invalid_regexp_instance.toString() crash
    (for ISDK/C 4.40e)

Bug: Calling the RegExp toString operator on an object that is not a valid RegExp instance will crash. E.G. RegExp.prototype.toString()

Fix: In srclib/ecma/seregexp.c, function RegExp_toString, at about line 128 change this code:

   orig = jseGetString(jsecontext,tmp,&len);

to this

   len = 0;
   orig = tmp ? jseGetString(jsecontext,tmp,&len) : UNISTR("");

  • Errors with extremely large Date values
    (for ISDK/C 4.40e)

Problem: Date values larger than the maximum allowable to new Date() can cause nearly-infinite loops.

Fix: In srclib/ecma/sedate.c, function do_date_construction(), near line 1109 find this block:

   else
   {
      value = jseGetNumberDatum(jsecontext,cv,NULL);
   }

and replace with this:

   else
   {
      value = jseGetNumberDatum(jsecontext,cv,NULL);
      value = TimeClip(jsecontext,value);
   }

  • during script compilation peephole optimizer accesses invalid memory
    (for ISDK/C 4.40e)

Problem: The peephole optimizer can access invalid memory during script compilation. In rare circumstance this may cause a crash.

Fix: In srccore/expressn.c, function secompileDelete, at about line 1052 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 1065 remove the "StartOpcodes" local variable and add these local variables instead:

   uint i, nxti;

and then at about line 1075 replace this block

   /* The array can move and its size can change, so need
    * to recalculate ending point each iteration.
    */
   StartOpcodes=This->opcodes;
   for( sptr = StartOpcodes; 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; i<This->opcodesUsed; )
   {
      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 1138, is an secompileDelete statement followed by a reference to SE_GLOBAL_NOTDIRECTXLAT. Insert a line between those two statement so it now reads:

   secompileDelete(This,sptr,&targetted,-change);
   sptr = This->opcodes + i;
   if ( SE_GLOBAL_NOTDIRECTXLAT <= c )

and finally, in this same function (at about line 1301) replace this line

   sptr = nxt;

with this line

   i = nxti;

  • sedbc bugs with long binary data
    (for ISDK/C 4.40e)

Problem: SEDBC can crash when reading from or writing to database columns representing any of the large binary data types.

Fix: In srclib/sedbc/jse_rfx.c, function jseFieldExchange_LongString(), case rf_value, at about line 2761 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.)

  • string.split() incorrect if regular expression used as separator
    (for ISDK/C 4.40e)

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 srclib/ecma/seobject.c, function Ecma_String_split(), at about line 3685 (just after the second call to SplitMatch) this of code:

   /* step 14 */
   JSE_POINTER_UINDEX e = 0;
   jseVariable tmp2,tmp = jseGetIndexMember(jsecontext,z,0);
   if( tmp )

should be changed to:

   /* step 14 */
   JSE_POINTER_UINDEX e;
   jseVariable tmp2,tmp;
   if ( R && 0!=jseGetIntegerDatum(jsecontext,z,JseStr(jsecontext,index)) )
   {
      jseDestroyVariable(jsecontext,z);
      q++;
      continue;
   }
   e = 0;
   tmp = jseGetIndexMember(jsecontext,z,0);
   if( tmp )

  • very short variable names incorrect if character > 0x7f
    (for ISDK/C 4.40e)

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 srccore/util.c, in the function CreateVarName, at about line 358 this statement:

   ret |= ((uword32)c) << shift;

should be changed to:

   ret |= ((uword32)(ujsechar)c) << shift;

  • fields of call structure and api_string structure may not be initialized
    (for ISDK/C 4.40e)

Bug: Some fields of the call and api_string_block structures may not be initialized. Specifically, the useCache boolean flag is sometimes checked before it is initialized, and each allocation of api_string_block is left in an uninitialized state. This has not been shown to cause any run-time errors, yet.

Fix: In srccore/call.c, function callInterpret(), at about line 1287, add a call to memset() following the existing call to jseMustMalloc(), so the code is now:

   call = jseMustMalloc(struct Call,sizeof(struct Call));
   memset(call,0,sizeof(struct Call));

and again in srccore/jselib.c, function jseCreateFiberContext(), add a call to memset() following the existing call to jseMustMalloc(), so the code is now:

   call = jseMustMalloc(struct Call,sizeof(struct Call));
   memset(call,0,sizeof(struct Call));

In srccore/util.c, function callApiStringEntry(), at about line 746, follow the line to jseMustMalloc() with a call to memset, so the code becomes:

   b = jseMustMalloc(struct api_string_block,sizeof(struct api_string_block));
   memset(b,0,sizeof(struct api_string_block));

  • variables on stack may be uninitialized during garbage collection
    (for ISDK/C 4.40e)

Problem: Temporary variables pushed on the stack may be uninitialized when the garbage collector executes. This may lead to corrupt script variables.

Fix: In the following cases, the macro STACK_PUSH should be immediately followed by the macro SEVAR_INIT_UNDEFINED. These are:

srccore/varutil.c, function seobjHasProperty(), at about line GetDotNamedVar(), at about line 3146, this code:

   tmp = STACK_PUSH;
   exists = ( 0 == (flags&HP_NO_PROTOTYPE) )

should become

   tmp = STACK_PUSH;
   SEVAR_INIT_UNDEFINED(tmp);
   exists = ( 0 == (flags&HP_NO_PROTOTYPE) )

In srccore/varutil.c, function sevarCallConstructor(), at about line 2191 this code

   tmp = STACK_PUSH;
   if( !seobjGetFuncVar(call,this,STOCK_STRING(call,_construct),tmp) )

should become

   tmp = STACK_PUSH;
   SEVAR_INIT_UNDEFINED(tmp);
   if( !seobjGetFuncVar(call,this,STOCK_STRING(call,_construct),tmp) )

In srccore/varutil.c, function GetDotNamedVar(), at about line 2293, these lines:

   tmp = STACK_PUSH;
   
   if( !seobjGetMember(call,hobj,varname,tmp) )

In srccore/secode.c, function secodeInterpet(), case sePreIncLocalWith, at about line 783, this code

   w_lhs = STACK_PUSH;
   w_rhs = STACK_PUSH; 

should become

   w_lhs = STACK_PUSH;
   w_rhs = STACK_PUSH; 
   SEVAR_INIT_UNDEFINED(w_lhs);

and finally in srccore\jselib.c, jseCallFunctionEx(), at about line 2895, this line

   onstack = STACK_PUSH;

should become this

   onstack = STACK_PUSH;
   SEVAR_INIT_UNDEFINED(onstack);

  • parseInt() treating characters ":;<=>?@" as digits 3 through 9
    (for ISDK/C 4.40e)

Problem: When evaluating a string, parseInt() is treating the characters from ":" to "@" (\x3A to \x40) as the digits 3 through 9.

Fix: In srclib/ecma/ecmamisc.c, function Ecma_parseInt, replace this line at about line 162:

   val = toupper_jsechar(JSECHARPTR_GETC(str))-'A'+10;

with this:

   if ( (val = toupper_jsechar(JSECHARPTR_GETC(str))-'A'+10) < 10 ) break;

  • Function.prototype.apply() not accepting null for thisObj parameter
    (for ISDK/C 4.40e)

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 srclib/ecma/seobject.c, function Ecma_Function_apply, at about line 463 replace this conditional:

   if( jseFuncVarCount(jsecontext) != 0 )

with this:

   if( jseFuncVarCount(jsecontext) != 0
    && jseTypeNull < jseGetType(jsecontext,jseFuncVar(jsecontext,0)) )

and at about line 475 replace this conditional statement

   if( jseFuncVarCount(jsecontext) > 1 )

with this

   if( jseFuncVarCount(jsecontext) > 1
    && jseTypeNull < jseGetType(jsecontext,jseFuncVar(jsecontext,1)) )

  • Documentation incorrect about lifetime of jseGetInternalString()
    (for ISDK/C 4.40e)

Problem: The documentation for the function jseGetInternalString(), states:

   The returned pointer is valid as long as
   the jseString 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 4.40e)

Problem: If interpreting jseInterpret(...SourceTrext...) 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 srccore/code.c, add this function:

      static const jsecharptr JSE_NEAR_CALL
   endOfSourceLine(const jsecharptr src)
   {
      jsechar c;
      do {
         JSECHARPTR_INC(src);
      } while ( (c = JSECHARPTR_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;

  • string slice() function is not accepting zero parameters
    (for ISDK/C 4.40e)

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 srclib/ecma/seobject.c, at about line 5005, change this line:

   JSE_PROTOMETH( UNISTR("slice"), Ecma_String_slice, 1, 2, jseDontEnum, jseFunc_Secure )

to this

   JSE_PROTOMETH( UNISTR("slice"), Ecma_String_slice, 0, 2, jseDontEnum, jseFunc_Secure )

and in function Ecma_String_slice() at about line 4065 change this line:

   start = jseGetLong(jsecontext,jseStart);

to this

   start = jseFuncVarCount(jsecontext) ? jseGetLong(jsecontext,jseStart) : 0;

and change the line at about 4052 from

   JSE_FUNC_VAR_NEED(jseStart,jsecontext,0,JSE_VN_CONVERT(JSE_VN_ANY,JSE_VN_NUMBER));

to

   if ( 0 != jseFuncVarCount(jsecontext) )
      JSE_FUNC_VAR_NEED(jseStart,jsecontext,0,JSE_VN_CONVERT(JSE_VN_ANY,JSE_VN_NUMBER));

  • setting array length to 0 does not remove all indexed properties
    (for ISDK/C 4.40e)

Bug: Setting the length property of an Array instance to zero does not remove the properties, although it does set the length to 0.

Fix: In srccore/var.c, function sevarSetArrayLength(), at about line 357 change the initialization of maxi to be:

   jsenumber maxi = JSE_FP_SUB(JSE_FP_CAST_FROM_ULONG(Length),jseOne);

  • 5-character variables names incorrect if either of last two characters is '$'
    (for ISDK/C 4.40e)

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 srccore/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 4.40d -- (may apply to earlier versions)

  • String replace may skip matches if replacement string is null-string (i.e. "")
    (for ISDK/C 4.40d)

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/se440/string_search_helper.txt

  • rare crashes on memory overwrites using the dynamicBuffer routines
    (for ISDK/C 4.40d)

Bug: Code may overwrite one byte beyond allocated memory when using the dynamicbuffer functions.

Fix: In srclib/common/selibutl.c, function dynamicBufferAppendLength(), at about line 138 change this line:

   if( buf->used + length > buf->allocated )

to this:

   if( buf->used + length >= buf->allocated )

and 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 4.40d)

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 4.40d. However, if you must apply these changes to 4.40d, follow the instructions at ftp://ftp.nombas.com/pub/isdkeval/se440/numidx.txt

  • Foo.prototype.constructor not assigned correctly for all builtin objects
    (for ISDK/C 4.40d)

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: In srclib/ecma/*.c locate all of the lines like this (where instead of "Foo" find "Function", "Object", "Array", "Boolean", "Number", "String", "Buffer", and "Date"):

   JSE_PROTOMETH( JseStr(jsecontext,constructor), Ecma_Foo_builtin, 0, 0,
                  jseDontEnum,  jseFunc_Secure ) 

and replace those lines with the following:

   JSE_VARASSIGN( UNISTR("prototype.constructor"), JseStr(jsecontext,Foo),
                  jseDontEnum )

Finally, the RegExp object is missing this relationship, and so add a statement like the above to the wrapper list in srclib/ecma/seregexp.c.

  • Array split() error for negative starting point
    (for ISDK/C 4.40d)

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 1592 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 4.40d)

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 380 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 4.40d)

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 srclib/clib/setime.c, function GenericTimeLib(), at about line 325 just after any of the ConversionFunc functions will have been called, insert this code:

   if ( t == NULL )
   {
      jseReturnVar(jsecontext,jseCreateVariable(jsecontext,jseTypeNull),jseRetTempVar);
      return;
   }

  • compilation errors if JSE_INSTANCEOF_HELPER defined
    (for ISDK/C 4.40d)

Bug: Compilation error for seobjfun.c if JSE_INSTANCEOF_HELPER is defined for using the jseInstanceof() function..

Fix: In srcmisc/seobjfun.c, make the following translations

   ORIG_PROTOTYPE_PROPERTY   ->   JseStr(jsecontext,prototype)
   PROTOTYPE_PROPERTY        ->   JseStr(jsecontext,_prototype)
   OBJECT_PROPERTY           ->   JseStr(jsecontext,Object)
   FUNCTION_PROPERTY         ->   JseStr(jsecontext,Function)

  • Number toString(with_radix) method is not handling NaN, Infinity, and -Infinity
    (for ISDK/C 4.40d)

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 2254 cahnge the JSE_NUMBER_TO_STRINGWITHRADIX code to be this:

   if ( 0 < jseFuncVarCount(jsecontext) )
   {
      slong radix = jseGetIntegerDatum(jsecontext,jseFuncVar(jsecontext,0),NULL);
      if ( radix==10  ||  !jseIsFinite(num) )
         EcmaNumberToString(jsecontext,buffer,num);
      else
         EcmaNumberToStringWithRadix(jsecontext,num,(sint)radix,buffer);
   }
   else

  • Invalid date computation on negative month
    (for ISDK/C 4.40d)

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 604 and 606 add code so those lines become:

   r6 = m%12;
   if ( r6 < 0 )
   {
      r6 += 12;
      r5--;
   }
   t = TimeFromYear(jsecontext,r5);

  • Math.round() returns -0 instead of +0 from -0.5 to -0
    (for ISDK/C 4.40d)

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 srclib/ecma/mathobj.c, function Ecma_Math_round, the "if" statement and block should be changed to:

   if ( jseIsFinite(val) && !jseIsZero(val) )
   {
      jsenumber 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(jsecontext,JSE_FP_ADD(val,half));
   }

  • Crash if reporting invalid data type while generating an error message
    (for ISDK/C 4.40d)

Bug: If a method is called during error handling, and that method has a data type or conversion error, then the program will crash. For example, in the following example "msg" is the wrong data type and while rerporing this error the program will crash:

   function TypeError(msg)
   {
      Error.apply(this, msg);
      return this;
   }
   TypeError(null);

Fix: In srccore/call.c, function callGetVarNeed(), after the call to callError() (at about line 2029), add this statement:

   CALL_SET_STATE(call,StateError);

  • Array .length should not be deletable
    (for ISDK/C 4.40d)

Bug: The .length property of any instance of an array should have the DontEnum attribute.

Fix: In srclib/ecma/seobject.c, function CreateNewObject(), at about line 3077 change

   jseSetAttributes(jsecontext,t2,jseDontEnum);

to

   jseSetAttributes(jsecontext,t2,jseDontEnum||jseDontDelete);

  • properties of the arguments object should be DontEnum
    (for ISDK/C 4.40d)

Bug: callee, length, and numbered members of the arguments object are enumerable, should be DontEnum.

Fix: In srccore/call.c, function callCreateArguments(), there are three calls to "seobjCreateMemberCopy()" each ending with the "SE_DEFAULT" parameter. In all three cases replace "SE_DEFAULT" with "jseDontEnum"

  • post-inc/decrement operator acts like pre-inc/decrement inside a "with" block
    (for ISDK/C 4.40d)

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 srccore/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 4.40d)

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 src/core/expressn.c, function secompilePostfixExpression(), change the EXPR_LOCAL case (approx line 2950):

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

  • loading pre-compiled scripts may use too much memory, or crash
    (for ISDK/C 4.40d)

Bug: When loading or interpreting from a precompiled script (i.e., created with jseCreateCodeTokenBuffer) the script engine may use an enormous amount of memory to load, or may crash on loading.

Fix: In srccore/token.c, function tokenReadString(), change this line (approx line 568):

   str = (jsecharptr) jseMustMalloc(jsechar,(size_t)len*sizeof(jsechar)+1/*so never 0*/);

to be this line:

   str = (jsecharptr) jseMustMalloc(jsechar,(size_t)(*len)*sizeof(jsechar)+sizeof(jsecharptrdatum));

  • use of undefined global variables do not always report error
    (for ISDK/C 4.40d)

Bug: When a variable that has not been declared or initialized is used to pass to a function, or is automatically assumed to be a function, e.g.:

   new String(blah);         // undeclared variable "blah" passed to a funcion
   var zoo = "" + blah.foo;  // undeclared variables treated as an object

no error message is generated.

Fix: In srccore/secode.c, function secodeInterpret(), within the case for sePushGlobal, sePushGlobalAsObject, and sePushGlobalParam, at about line 1287 is this large block of code:

   if( jseOptReqVarKeyword & call->Global->ExternalLinkParms.options )
   {
      callQuit(call,textcoreFUNC_OR_VAR_NOT_DECLARED,mem);
      break;
   }
   if( t==sePushGlobal )
   {
      callQuit(call,textcoreVAR_TYPE_UNKNOWN,GetStringTableEntry(call,mem,NULL));
      break;
   }
   else
   {
      struct seObjectMem *smem = NULL; /* initialization to shut up compiler */
      ...etc...
   }

replace that entire block with these five lines:

   callQuit(call,textcoreVAR_TYPE_UNKNOWN,GetStringTableEntry(call,mem,NULL));
   break;

This change will cause error reports if you are using the non-ECMA compile-time option JSE_AUTO_OBJECT and are relying on scripts such as those above to automatically create object variables. One consequence of this is that the non-Ecma function defined() will cease to functions as expected in pre-processor statements such as

   #if defined(Clib.puts) 

This should only be a problem if you use the JSE_CONDITIONAL_COMPILE option. In future releases SE:ISDK will move processing of defined() into the pre-processor for JSE_CONDITIONAL_COMPILE builds. If you need this pre-processor code ask Tech Support, or change defined() to use typeof(). For example, the above statement would become

   #if typeof(Clib)!="undefined" && typeof(Clib.puts)!="undefined"

  • debugger displays "no filename" for preprocessor directives
    (for ISDK/C 4.40d)

Bug: When debugging scripts that are using preprocessor directives (e.g., #if __JSE_WIN32__) the debugger will display that it cannot find "no filename". After that message, no debugging is possible. This applies to local debugging with SEDBGW32.EXE and remote debugging with SEDBXW32.EXE

Fix: In srcdbg/debugme.c there are two instances of the following line (at line 1218 and line 1465):

   if ( NULL == (filename = jseLocateSource(jsecontext,&linenum)) )

replace both instances with the following code:

   if ( NULL == (filename = jseLocateSource(jsecontext,&linenum))
     || !strcmp(filename,"no filename") )

  • invalid assert for operator overloading on unary operators
    (for ISDK/C 4.40d)

Bug: If overloading unary operators with jseSetObjectCallbacks, and NDEBUG is not defined, and invalid assert will be triggered.

Fix: In srccore/varutil.c, function seobjCallDynamicProperty(), at about line 2626, replace this block of code:

      if( dynacallPut == whichCall
   #   if JSE_OPERATOR_OVERLOADING!=0
       || dynacallOperator == whichCall
   #   endif
       || dynacallDefaultvalue == whichCall )
      {
         assert( Parameter2!=NULL );
      }

with this block:

      if( dynacallPut == whichCall
       || dynacallDefaultvalue == whichCall )
      {
         assert( Parameter2!=NULL );
      }
   #  if JSE_OPERATOR_OVERLOADING!=0
      else if ( dynacallOperator == whichCall )
      {
         /* Parameter2 may or may not be NULL for overloading (because it may be
          * two operators, or a unary operator. No test.
          */
      }
   #  endif

 

  • 'new' operator accepting non-Object return values
    (for ISDK/C 4.40d)

Bug: If a constructor returns a variable that is not an object then that return value is not being ignored, although it should be. For example, in the following example foo should be set to a new Object and not 834.

   function foomaker()
   {
      return 834;
   }
   var foo = new foomaker();

Fix: In srccore/call.c, function callReturnFromFunction(), at about line 906 replace this line:

   if( SEVAR_GET_TYPE(rTmp)==VUndefined )

with this block:

   if ( SEVAR_GET_TYPE(rTmp)!=VObject  &&  SEVAR_GET_TYPE(&(call->default_return))==VObject )

  • operator overloading crashes with some operators
    (for ISDK/C 4.40d)

Bug: se440 operator overloading crashes when using some of the operators.

Fix: In srccore/secode.c, function secodeInterpret(), locate the case block beginning with this code at line 2336:

   case seMultiply: case seDivide:
   case seModulo: case seShiftLeft: case seSignedShiftRight:
   case seUnsignedShiftRight: case seBitOr: case seBitXor: case seBitAnd:

a few lines below that (line 2347) replace "r_rhs" with "w_rhs" so the line changes from

   IF_OPERATOR_NOT_OVERLOADED(call,w_lhs,r_rhs,t)

to

   IF_OPERATOR_NOT_OVERLOADED(call,w_lhs,w_rhs,t)

  • jseCallFunction return variable may be NULL with JSE_FUNC_TRAP_ERRORS
    (for ISDK/C 4.40d)

Bug: In jseCallFunction() and jseCallFunctionEx(), if the JSE_FUNC_TRAP_ERROS flag is used and returnVar is not NULL then *returnVar is supposed to be assign to some non-NULL value. But in some cases (usually if a parameter is not a valid function) this will return with a non-NULL *returnVar

Fix: In srccore/jselib.c, function jseCallFunctionEx(), at about line 2821 replace this block:

   # if ( 0 < JSE_API_ASSERTLEVEL )
   if ( NULL == func )
   {
      # if JSE_NAMED_PARAMS==1
      STACK_POPX((uint)(2+((flags&JSE_FUNC_NAMED_PARAMS)?1:0)));
      # else
      STACK_POPX(2);
      # endif
      
      SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
      END_TIMING(call);
      return False;
   }
   # endif

with this block:

   if ( NULL == func )
   {
      # if JSE_NAMED_PARAMS==1
         STACK_POPX((uint)(2+((flags&JSE_FUNC_NAMED_PARAMS)?1:0)));
      # else
         STACK_POPX(2);
      # endif
      # if ( 0 < JSE_API_ASSERTLEVEL )
         SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
      # endif
      END_TIMING(call);
      goto illegal_params;
   }

then at about line 2781 replace this block:

   # if JSE_NAMED_PARAMS==1
      /* To keep it from being collected */
      if( (flags & JSE_FUNC_NAMED_PARAMS)!=0 )
      {
         args = STACK_PUSH;
         SEVAR_INIT_BLANK_OBJECT(call,args);
         args_obj = SEVAR_GET_OBJECT(args);
      }
   #endif

with this:

   if( SEVAR_GET_TYPE(rvar)!=VObject )
   {
      # if ( 0 < JSE_API_ASSERTLEVEL )
         SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
      # endif
      END_TIMING(call);
      goto illegal_params;
   }

Next, replace the remaining three instances of "return False" to instead be "goto illegal_params".

Finally, at this block of code at the end of the function, after "return retbool";

 illegal_params:
   *retvar = NULL;
   {
      jseVariable func = jseGetMember(jsecontext,NULL,UNISTR("Error"));
      if( func )
      {
         jseStack stack;
         jseVariable param;
   
         stack = jseCreateStack(jsecontext);
         param = jseCreateVariable(jsecontext,jseTypeString);
         jsePutString(jsecontext,param,UNISTR("API parameters are invalid"));
         jsePush(jsecontext,stack,param,TRUE);
   
         if( !jseCallFunction(jsecontext,func,stack,retvar,NULL) )
         {
            if( *retvar!=NULL )
            {
               jseDestroyVariable(jsecontext,*retvar);
               *retvar = NULL;
            }
         }
         jseDestroyStack(jsecontext,stack);
      }
   }
   
   if( *retvar==NULL )
   {
      *retvar = jseCreateVariable(jsecontext,jseTypeString);
      jsePutString(jsecontext,*retvar,UNISTR("API parameters are invalid"));
   }
   
   return FALSE;

  • crash when reporting invalid #include syntax
    (for ISDK/C 4.40d)

Bug: If JSE_INCLUDE option is enabled, and there is a parsing error in an "#include" source line, such as this:

   #include <blah'

an invalid pointer during error reporting will lead to a crash.

Fix: In srcore/source.c, function sourceInclude(), the two calls to callError() which each receive "textcoreIncludeDirective" as the final parameter should instead receive "textcoreGetStatic(call,textcoreIncludeDirective)" as the final parameter. In other words, lines 758 and 769 should both change from

   textcoreIncludeDirective);

to

   textcoreGetStatic(call,textcoreIncludeDirective));

  • insufficient checks on bad dates
    (for ISDK/C 4.40d)

Bug: Some of the functions in the Date object are not testing against invalid dates. The results may be incorrrect, assertioins may be triggered, or floating-point exceptions may be triggered.

Fix: In srclib/ecma/sedate.c, a few locations need jseIsFinite() tests against the internal date representation. In function SetYearMonDay(), add a test after the call to jseGetNumber() at about line 1974 so it reads:

   t = jseGetNumber(jsecontext,
                    jseMember(jsecontext,thisvar,JseStr(jsecontext,_date_value_),jseTypeNumber));
   if ( !jseIsFinite(t) )
      return;

and in SetHourMinSecMilli() add a test after jseGetNumber() at about line 1829 so it reads:

   t = jseGetNumber(jsecontext,
                    jseMember(jsecontext,thisvar,JseStr(jsecontext,_date_value_),jseTypeNumber));
   if ( !jseIsFinite(t) )
      return;

and in Ecma_Date_toSystem() add a test after jseGetNumberDatum() at about line 1258 so it reads

   units = jseGetNumberDatum(jsecontext,thisvar,JseStr(jsecontext,_date_value_));
   if ( !jseIsFinite(units) )
      return NULL;

  • compound assignment (/=, *=, %=, +=, -=, <<=, &=, ^=, |=) ignoring with() blocks
    (for ISDK/C 4.40d)

Bug: The object for a with(object) block is ignored when evaluating the initial variable while evaluating a compound assignment.

Fix: In srccore/expressn.c, function secompileGetValueKeep(), at about line 2791, this statement

   if( this->with_depth )

should instead be this:

   if( !this->with_depth )

  • error concatenating C-style string constants
    (for ISDK/C 4.40d)

Bug: When concatenating source strings without the '+' operator, as in this code:

   var foo = "dog" "house"

which should behave the same as this code:

   var foo = "dog" + "house"

it is possible for other string constants to get overwritten.

Fix: In srccore/expressn.c, function secompilePrimaryExpression(), at about line 2224, remove these two lines following the comment "/* Remove the last two string constants...":

   /* SEOBJECT_PUT(this->call,this->constObj,used,
    *             SEOBJECT_GET(this->call,this->constObj,used)-2);
    */

or, because this C-like string-concateation behavior is not part of the ECMAScript standard, you may choose to remove the entire for(;;) loop containing this statement, from line 2184 to 2233.

  • invalid name accessing local parameters in a with() block
    (for ISDK/C 4.40d)

Bug: When accessing a variable in a with block, the wrong variable name is used when testing a variable against the with object if the variables is an argument to the function (and not the first argument). In some cases this will lead to accessing the wrong name. If this with object has a get or hasproperty callback this may cause a program crash. The following example demonstrates where this may fail:

   function foo(argument1,argument2,argument3)
   {
      var local1, local2, local3;
      with ( someObject )
      {
         local1 = local2;      // OK
         local1 = local3;      // OK
         local1 = argument1;   // OK
         local1 = argument2;   // FAIL
         local1 = argument3;   // FAIL
      }
   }

Fix: In srccore/secode.c, function callWithCatchEntry(), at about line 405, change this line:

   [ (index<=0) ? index : ((struct LocalFunction *)FUNCPTR)->localItems.InputParameterCount+

to this

   [ (index<=0) ? -index : ((struct LocalFunction *)FUNCPTR)->localItems.InputParameterCount+

Note that just a single "-" was added.

  • MSVC6 memory allocation bugs
    (for ISDK/C 4.40d)

Bug: Problems with Microsoft's C++ in Microsoft Visual C++ 6.0, can cause heap allocation errors and memory overwrites that can cause crashes that are extremely erratic and hard to reproduce.

Fix: If you are using MSVC6, download and install the Visual Studio 6.0 Service Pack 5 from http://msdn.microsoft.com/vstudio/sp/vs6sp5/

  • for...in fails to iterate through inherited properties
    (for ISDK/C 4.40d)

Bug: In some cases, such as when an object inherits from a script object via "new Foo()", for...in may not iterate through all inherited properties.

Fix: A replacement for the function seGotoForIn_Operator(), in srccore/operator.c, may be downloaded from ftp://ftp.nombas.com/pub/isdkeval/se440/segotoforin_operator.zip

  • aboutopt.jse doesn't work
    (for ISDK/C 4.40d)

Bug: tools/aboutopt.jse isn't working with any of the samples. When a finer grain was added to what functions could be added/removed, we did not update aboutopt. Also, it wasn't clear how to execute the abotopt.jse scripts.

Fix: Updated files for aboutopt.jse may be downloaded from ftp://ftp.nombas.com/pub/isdkeval/se440/aboutopt.zip. This aboutopt.jse can be execute frim the compiled SIMPLE1 sample, with a statement such as:

   W32Simp1.exe tools\aboutopt.jse seisdk\samples\simple1\jseopt.h __JSE_WIN32__ _MSC_VER JSE_ASCII

  • terminating execution from within a "try" block will cause memory leaks
    (for ISDK/C 4.40d)

Bug: If execution is terminated while a script is within a try block, such as if the jseMayIContinue callback function returns False, then some allocated memory will not be freed.

Fix: In srccore/call.c, function callDelete(), add this to the local variables at the beginning of the function:

   struct TryBlock *loop;

and add this block to the end of the function, just before the jseMustFree(call) statement at about line 1543:

   for( loop = call->tries;loop!=NULL; )
   {
      struct TryBlock *prev = loop->prev;
   
      jseMustFree(loop);
      loop = prev;
   }

  • seObjHasProperty causing floating-point overflow if not handled by callback
    (for ISDK/C 4.40d)

Bug: On some systems, if an object has a hasProp callback that does not return HP_HAS or HP_HASNOT, or if the dynamic object does not have a hasProp, then a floating-point overflow exception can occur.

Fix: In srccore/varutil.c, function seobjHasProperty(), at line 3034 change this line:

   ret = (jsebool)JSE_FP_CAST_TO_SLONG(SEVAR_GET_NUMBER_VALUE(value));

to this:

   if ( handled )
      ret = (jsebool)JSE_FP_CAST_TO_SLONG(SEVAR_GET_NUMBER_VALUE(value));

  • "+Infinity and "-Infinity" converted to NaN if JSE_FLOATING_POINT==0
    (for ISDK/C 4.40d)

Bug: If building in integer-only mode (i.e. #define JSE_FLOATING_POINT 0), "+Infinity" and "-Infinity" will be read incorrectly and converted to NaN.

Fix: In srccore/util.c, function convertStringToNumber(), there are two places with this block of code (line 2228 and 2235):

   #           if (0!=JSE_FLOATING_POINT)
                  lenParsed++;
   #           endif

in both cases the conditionals should be removed, so the above blocks are replaced with the single line:

               lenParsed++;

  • memory leak, and possible crash, using the #link statement
    (for ISDK/C 4.40d)

Bug: Memory leaks and possible crashes using the #link statement. The memory leak fix is for Unix only, but the possible crash in running out of memory applies to all systems.

Fix: In srccore/extlib.c, function extensionFindLibPath(), at about line 529, replace this line:

   if( !Success )

with this

 if( !Success && FileName!=NULL )

and extensionLibraryStartup(), at about line 627 replace this block

   #if defined(__JSE_UNIX__)
      {
         jsechar buffer[256];
         jse_sprintf(buffer,"lib%s",LibraryName);
         FullLibraryPath = extensionFindLibPath(this,buffer,call);
      }
      if( FullLibraryPath==NULL || FullLibraryPath[0]=='\0' )
   #endif
         FullLibraryPath = extensionFindLibPath(this,LibraryName,call);

with this block

   #if defined(__JSE_UNIX__)
      {
         jsechar buffer[256];
         jse_sprintf(buffer,"lib%s",LibraryName);
         FullLibraryPath = extensionFindLibPath(this,buffer,call);
      }
      if(FullLibraryPath == NULL || JSECHARPTR_GETC(FullLibraryPath)==UNICHR('\0'))
      {
         if( FullLibraryPath!=NULL ) jseMustFree(FullLibraryPath);
         FullLibraryPath = extensionFindLibPath(this,LibraryName,call);
      }
   #else
      FullLibraryPath = extensionFindLibPath(this,LibraryName,call);
   #endif

and then at about line 640, replace this block

   callError(call,textcoreLINK_LIBRARY_NOT_EXISTS,LibraryName);
   jseMustFree(FullLibraryPath);
   return False;

with this

     callError(call,textcoreLINK_LIBRARY_NOT_EXISTS,LibraryName);
   if( FullLibraryPath ) jseMustFree(FullLibraryPath);
   return False;

for 4.40c -- (may apply to earlier versions)

  • altering "arguments" causes assertion failure
    (for ISDK/C 4.40c)

Problem: Using "var" or assigning to the "arguments" variable will cause an assertion failure in !NDEBUG versions.

Fix: In srccore/call.c, function callCreateVariableObject(), at about line 1230, replace this code:

seobjCreateMemberCopy(call,tmpobj,STOCK_STRING(call,arguments),tmp,SE_DEFAULT);

with this code:

seobjNewMember(call,tmpobj,STOCK_STRING(call,arguments),
               tmp,jseDontDelete,SE_NM_CREATE);

  • error marking more than MARK_STACK_SIZE objects
    (for ISDK/C 4.40c)

    Bug: If there are more than MARK_STACK_SIZE tied to the call->Global object, then some objects may never be marked and so may be freed while still in use. This is could happen in any configuration, but is most likely in a JSE_MIN_MEMORY build working on a large script with many global function variables.

    Fix: The algorithm related to MARK_STACK_SIZE has been fixed in garbage.c of the 4.40d release. Get that release.

  • ToNumber() returns incorrect values for "+" and "-"
    (for ISDK/C 4.40c)

    Bug: When ToNumber() is called with either "+" or "-" as its argument, the return value should be NaN. Instead, ToNumber() is returning Infinity and -Infinity, respectively.

    Fix: In srccore/util.c, function convertStringToNumber(), at about line 2260, change this code:

       if ( lenParsed == lenStr )
       {
          val = neg ? jseNegInfinity : jseInfinity ;
       }

    to this

       if ( lenParsed == lenStr && 2<lenStr )
       {
          val = neg ? jseNegInfinity : jseInfinity ;
       }

  • Object comparisons with wrong hint - Date comparisons fail
    (for ISDK/C 4.40c)

    Bug: Object comparison (<, <=, >, >=) are not correctly following the hint logic specified in section 11.8.5 (The Abstract Relational Comparison Algorithm) of the ECMAScript specification. When objects are converted to a primitive value for comparison they should be give "hint Number". This would only show up as a problem for any object that does not have number as its default primitive; the Date object is such an example, and so the following test fails for the date object because it is comparing as a string (the default Date primitive type) instead of as a Nuimber (the hint type for comparison).

  •    newer = new Date("Thu Oct 4 15:54:25 2001");
       older = new Date("Tue Sep 25 15:54:25 2001");
       Test.assert( older < newer ); // fails because comparing as string

    Fix: In srccore/varutil.c, function sevarECMACompareLess(), change the first two instances of this code (at lines 782 and 791):

       sevarConvert(call,tmp,jseToPrimitive);

    to this

       sevarConvertToPrimitive(call,tmp,VNumber);

  • SEObjectWrapper not deleting createVariable() objects
    (for ISDK/C 4.40c)

    Bug: the underlying variable reference created by SEObjectWrapper::createVariable() is not being destroyed when the SEObjectWrapper C++ object is deleted.

    Fix: In srcapp/jseobject.cpp, function SEObjectWrapper::deleteHook(), at about line 179, the first line of the function should be changed from:

  •    if ( NULL == propName )
    to
       if ( NULL != propName )

    and a few lines down this statement may be removed:

       const jsecharptr propString = jseGetInternalString(jsecontext,...);

  • jseReturnVar may crash with strings, buffers, and objects
    (for ISDK/C 4.40c)

    Bug: It is possible, although very unlikely, that variables of type jseTypeString, jseTypeBuffer, or jseTypeObject may be freed by the garbage collector before they are assigned to a script variable.

    Fix: In srccore/garbage.c, function mark(), at about line 847, locate these lines:

  •    if( CALL_ERROR(mstackinfo.call) )
          MARK_VARIABLE(&(mstackinfo.call->return_var),&mstackinfo);

    and remove the "if" statement so that MARK_VARIABLE() is always called on the return_var.

 

  • jseMemberEx and jseIndexMemberEx do not search prototypes
    (for ISDK/C 4.40c)

    Warning: In moving from version 4.30 to 4.40, and if you were using the jseMemberEx() or jseIndexMemberEx() functions without the jseDontSearchPrototype flag, then you will find that with version 4.40 members will not be located in the _prototype chain. This is because jseDontSearchPrototype is assumed for jseMemberEx and jseIndexMemberEx, as they are used to force creation of a member.

    Fix: If you are expecting to use an existing member, then instead of any of the jseMember???() or jseIndexMember???() functions you should be using the jseGetMember???() or jseGetIndexMember???() functions.

 

  • toString on functions concatenates some identifiers
    (for ISDK/C 4.40c)

    Bug: When a function is being converted to a string, a required space may not be displayed after some variables. For example, this code:

  • function blah()
    {
       for (var prop in obj);
    }
    display("" + blah);

may produce this output (note that "prop" and "in" have become concatenated):

function blah()
{
   for (var propin obj);
}

Fix: In srccore/function.c, function functionTextAsVariable(), at about line 249, change the seTokIdentifier to add a space after each identifier, as in:

else if( type==seTokIdentifier )
{
   growingAddTo(&buff,GetStringTableEntry(call,tokGetName(c),NULL));
   growingAddTo(&buff,UNISTR(" "));
}

 

  • named-parameter object for wrapper functions trashed by GC
    (for ISDK/C 4.40c)

  • Problem: If garbage collection occurs while a named-parameter object is available to a wrapper function, that named-parameter object will be freed and its use may crash the system.

    Fix: In srccore/util.c, function mark(), near line 844, locate these lines:

    if( mstackinfo.call->hVariableObject!=hSEObjectNull )
       MARK_OBJECT(mstackinfo.call->hVariableObject,&mstackinfo);

    and after those lines add this code:

    if( mstackinfo.call->wrapper_named!=hSEObjectNull )
       MARK_OBJECT(mstackinfo.call->wrapper_named,&mstackinfo);            

 

  • "internal stack exhausted" error with multiple calls to jseCallFunction()
    (for ISDK/C 4.40c)

    Bug: jseCallFunction() leaks ScriptEase stack space, leading to an overflow and the 'internal stack exhausted' error.

    Fix: In srccore/jselib.c, function jseCallFunctionEx(), at about line 2937 is a call to callFunctionFully(). Immediately after callFunctionFull() add a STACK_POP statement, so those lines become:

    callFunctionFully(...);
    STACK_POP;
    call->Global->call_func_mark = call_func_mark_save;
    

 

  • get callback may crash during seobjHasProperty()
    (for ISDK/C 4.40c)

Bug: dynamic get callback crash when called during seobjHasProperty() to determine if the propery exists.

Fix: In srccore/varutil.c, function seobjHasProperty(), at about line 3002 change this line:

    if( dest ) assert( sevarIsValid(call,dest) );

to this:

    assert( dest==NULL  ||  sevarIsValid(call,dest) );

and at about line 3058 move the STACK_POP after the if block, instead of before the if block, and insert a statement before the following STACK_POP, so the code is:

       jsebool ret = (SEVAR_GET_TYPE(dest)!=VUndefined) || handled;
       if( ret && (flags&HP_REFERENCE)!=0 )
       {
          SEVAR_INIT_REFERENCE(dest,hobj,propname);
       }
       STACK_POP;
       return ret;
    }
    if ( dest==rhs ) dest = NULL;
    STACK_POP;

 

   

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

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