(Not part of Communicator build.)

Fix 123552 Array length updating is incorrect
This commit is contained in:
norris 1998-06-12 00:10:52 +00:00
Родитель 3348b831c0
Коммит b6ded7a99f
2 изменённых файлов: 86 добавлений и 33 удалений

Просмотреть файл

@ -38,6 +38,9 @@
#include "jsobj.h"
#include "jsstr.h"
/* 2^32 - 1 as a number and a string */
#define MAXINDEX 4294967295u
#define MAXSTR "4294967295"
/* Determine if the id represents an array index.
*
@ -59,7 +62,7 @@ IdIsIndex(jsid id, jsuint *indexp)
{
jsuint i;
JSString *str;
jschar *ep;
jschar *cp;
if (JSVAL_IS_INT(id)) {
i = JSVAL_TO_INT(id);
@ -71,21 +74,31 @@ IdIsIndex(jsid id, jsuint *indexp)
/* It must be a string. */
str = JSVAL_TO_STRING(id);
ep = str->chars;
if (str->length == 0 || *ep < '1' || *ep > '9')
return JS_FALSE;
i = 0;
while (*ep != 0 && JS7_ISDEC(*ep)) {
jsuint i2 = i*10 + (*ep - '0');
if (i2 < i)
return JS_FALSE; /* overflow */
i = i2;
ep++;
cp = str->chars;
if (JS7_ISDEC(*cp) && str->length < sizeof(MAXSTR)) {
jsuint index = JS7_UNDEC(*cp++);
jsuint oldIndex = 0;
jsint c;
if (index != 0) {
while (JS7_ISDEC(*cp)) {
oldIndex = index;
c = JS7_UNDEC(*cp);
index = 10*index + c;
cp++;
}
}
/* Make sure all characters were consumed and that it couldn't
* have overflowed.
*/
if (*cp == 0 &&
(oldIndex < (MAXINDEX / 10) ||
(oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
{
*indexp = index;
return JS_TRUE;
}
}
if (*ep != 0 || i == 4294967295) /* 4294967295 == 2^32-1 */
return JS_FALSE;
*indexp = i;
return JS_TRUE;
return JS_FALSE;
}

Просмотреть файл

@ -1233,24 +1233,33 @@ js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
#define CHECK_FOR_EMPTY_INDEX(id) /* nothing */
#endif
/* JSVAL_INT_MAX as a string */
#define JSVAL_INT_MAX_STRING "1073741823"
#define CHECK_FOR_FUNNY_INDEX(id) \
PR_BEGIN_MACRO \
if (!JSVAL_IS_INT(id)) { \
if (!JSVAL_IS_INT(id)) { \
JSAtom *_atom = (JSAtom *)id; \
JSString *_str = ATOM_TO_STRING(_atom); \
const jschar *_cp = _str->chars; \
if (JS7_ISDEC(*_cp)) { \
jsint _index = JS7_UNDEC(*_cp); \
_cp++; \
if (_index != 0) { \
while (JS7_ISDEC(*_cp)) { \
_index = 10 * _index + JS7_UNDEC(*_cp); \
if (_index < 0) \
break; \
_cp++; \
} \
} \
if (*_cp == 0 && INT_FITS_IN_JSVAL(_index)) \
if (JS7_ISDEC(*_cp) && \
_str->length <= sizeof(JSVAL_INT_MAX_STRING)-1) \
{ \
jsuint _index = JS7_UNDEC(*_cp++); \
jsuint _oldIndex = 0; \
jsuint _c; \
if (_index != 0) { \
while (JS7_ISDEC(*_cp)) { \
_oldIndex = _index; \
_c = JS7_UNDEC(*_cp); \
_index = 10*_index + _c; \
_cp++; \
} \
} \
if (*_cp == 0 && \
(_oldIndex < (JSVAL_INT_MAX / 10) || \
(_oldIndex == (JSVAL_INT_MAX / 10) && \
_c < (JSVAL_INT_MAX % 10)))) \
id = INT_TO_JSVAL(_index); \
} else { \
CHECK_FOR_EMPTY_INDEX(id); \
@ -1258,6 +1267,7 @@ js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
} \
PR_END_MACRO
JSBool
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
@ -1267,7 +1277,8 @@ js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSScope *scope;
JSScopeProperty *sprop;
/* Handle old bug that treated empty string as zero index. */
/* Handle old bug that treated empty string as zero index.
* Also convert string indices to numbers if applicable. */
CHECK_FOR_FUNNY_INDEX(id);
/* Lock if object locking is required by this implementation. */
@ -1337,7 +1348,8 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
JSObject *obj2, *proto;
JSScopeProperty *sprop;
/* Handle old bug that treated empty string as zero index. */
/* Handle old bug that treated empty string as zero index.
* Also convert string indices to numbers if applicable. */
CHECK_FOR_FUNNY_INDEX(id);
/* Search scopes starting with obj and following the prototype link. */
@ -1538,7 +1550,8 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop))
return JS_FALSE;
if (!sprop) {
/* Handle old bug that treated empty string as zero index. */
/* Handle old bug that treated empty string as zero index.
* Also convert string indices to numbers if applicable. */
CHECK_FOR_FUNNY_INDEX(id);
#if JS_BUG_NULL_INDEX_PROPS
@ -1603,7 +1616,8 @@ js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return JS_FALSE;
}
/* Handle old bug that treated empty string as zero index. */
/* Handle old bug that treated empty string as zero index.
* Also convert string indices to numbers if applicable. */
CHECK_FOR_FUNNY_INDEX(id);
hash = js_HashValue(id);
@ -1875,7 +1889,8 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
*rval = JSVERSION_IS_ECMA(cx->version) ? JSVAL_TRUE : JSVAL_VOID;
/* Handle old bug that treated empty string as zero index. */
/* Handle old bug that treated empty string as zero index.
* Also convert string indices to numbers if applicable. */
CHECK_FOR_FUNNY_INDEX(id);
if (!js_LookupProperty(cx, obj, id, &proto, &prop))
@ -2435,3 +2450,28 @@ out:
}
#endif /* JS_HAS_XDR */
#ifdef DEBUG
void printId(jsid id) {
jsuint i;
JSAtom *atom;
JSString *str;
fprintf(stderr, "id %d (0x%x) = ", id, id);
if (JSVAL_IS_INT(id)) {
fprintf(stderr, "%d\n", JSVAL_TO_INT(id));
} else {
atom = (JSAtom *)id;
str = ATOM_TO_STRING(atom);
fputc('"', stderr);
for (i=0; i < str->length; i++)
fputc(str->chars[i], stderr);
fputc('"', stderr);
fputc('\n', stderr);
}
fflush(stderr);
}
#endif