Integration
SDK 4.40x Errata
Fixes Affecting Users of the ScriptEase
ISDKs
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
- String
replace may skip matches if replacement string
is null-string (i.e. "")
- rare
crashes on memory overwrites using the dynamicBuffer
routines
- Problems
with array lengths and numeric indices that
are large or non-integer
- Foo.prototype.constructor
not assigned correctly for all builtin objects
- Array
split() error for negative starting point
- Math.min(+0,-0)
wrongly returns +0
- Clib.localtime()
and Clib.gmtime() crash on out-of-range dates
- compilation
errors if JSE_INSTANCEOF_HELPER defined
- Number
toString(with_radix) method is not handling
NaN, Infinity, and -Infinity
- Invalid
date computation on negative month
- Math.round()
returns -0 instead of +0 from -0.5 to -0
- Crash
if reporting invalid data type while generating
an error message
- Array
.length should not be deletable
- properties
of the arguments object should be DontEnum
- post-inc/decrement
operator acts like pre-inc/decrement inside
a "with" block
- post-increment
operator on local variable is ignoring "with"
statement
- loading
pre-compiled scripts may use too much memory,
or crash
- use
of undefined global variables do not always
report error
- debugger
displays "no filename" for preprocessor
directives
- invalid
assert for operator overloading on unary operators
- 'new'
operator accepting non-Object return values
- operator
overloading crashes with some operators
- jseCallFunction
return variable may be NULL with JSE_FUNC_TRAP_ERRORS
- crash
when reporting invalid #include syntax
- insufficient
checks on bad Dates
- compound
assignment (/=, *=, %=, +=, -=, <<=, &=,
^=, |=) ignoring with() blocks
- error
concatenating C-style string constants
- invalid
name accessing local parameters in a with()
block
- MSVC6
memory allocation bugs
- for...in
fails to iterate through inherited properties
- aboutopt.jse
doesn't work
- terminating
execution from within a "try" block
will cause memory leaks
- seObjHasProperty
causing floating-point overflow if not handled
by callback
- "+Infinity
and "-Infinity" converted to NaN if
JSE_FLOATING_POINT==0
-
memory leak, and possible
crash, using the #link statement
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:
to
this:
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;
|