Disallow non-canonical jsids, bug 751331. r=luke

This commit is contained in:
Brian Hackett
2012-05-06 13:45:19 -07:00
parent a8d6820bef
commit 33a75298e8
58 changed files with 511 additions and 655 deletions

View File

@@ -540,125 +540,48 @@ IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
if (!atom)
return false;
*idp = ATOM_TO_JSID(atom);
JS_ASSERT(js_CheckForStringIndex(*idp) == *idp);
*idp = JSID_FROM_BITS((size_t)atom);
return true;
}
bool
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp)
{
#if JS_HAS_XML_SUPPORT
if (idval.isObject()) {
JSObject *idobj = &idval.toObject();
if (obj && obj->isXML()) {
*idp = OBJECT_TO_JSID(idobj);
*vp = idval;
return true;
}
if (js_GetLocalNameFromFunctionQName(idobj, idp, cx)) {
*vp = IdToValue(*idp);
return true;
}
if (!obj && idobj->isXMLId()) {
*idp = OBJECT_TO_JSID(idobj);
*vp = idval;
return JS_TRUE;
}
}
#endif
JSAtom *atom;
if (!js_ValueToAtom(cx, idval, &atom))
return false;
*idp = AtomToId(atom);
vp->setString(atom);
return true;
}
} /* namespace js */
/* JSBOXEDWORD_INT_MAX as a string */
#define JSBOXEDWORD_INT_MAX_STRING "1073741823"
/*
* Convert string indexes that convert to int jsvals as ints to save memory.
* Care must be taken to use this macro every time a property name is used, or
* else double-sets, incorrect property cache misses, or other mistakes could
* occur.
*/
jsid
js_CheckForStringIndex(jsid id)
{
if (!JSID_IS_ATOM(id))
return id;
JSAtom *atom = JSID_TO_ATOM(id);
const jschar *s = atom->chars();
jschar ch = *s;
JSBool negative = (ch == '-');
if (negative)
ch = *++s;
if (!JS7_ISDEC(ch))
return id;
size_t n = atom->length() - negative;
if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
return id;
const jschar *cp = s;
const jschar *end = s + n;
uint32_t index = JS7_UNDEC(*cp++);
uint32_t oldIndex = 0;
uint32_t c = 0;
if (index != 0) {
while (JS7_ISDEC(*cp)) {
oldIndex = index;
c = JS7_UNDEC(*cp);
index = 10 * index + c;
cp++;
}
}
/*
* Non-integer indexes can't be represented as integers. Also, distinguish
* index "-0" from "0", because JSBOXEDWORD_INT cannot.
*/
if (cp != end || (negative && index == 0))
return id;
if (negative) {
if (oldIndex < -(JSID_INT_MIN / 10) ||
(oldIndex == -(JSID_INT_MIN / 10) && c <= (-JSID_INT_MIN % 10)))
{
id = INT_TO_JSID(-int32_t(index));
}
} else {
if (oldIndex < JSID_INT_MAX / 10 ||
(oldIndex == JSID_INT_MAX / 10 && c <= (JSID_INT_MAX % 10)))
{
id = INT_TO_JSID(int32_t(index));
}
}
return id;
}
#if JS_HAS_XML_SUPPORT
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
*idp = OBJECT_TO_JSID(&idval.toObject());
return true;
}
if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx))
return true;
return js_ValueToStringId(cx, idval, idp);
}
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
JSObject &idobj = idval.toObject();
*idp = OBJECT_TO_JSID(&idobj);
vp->setObject(idobj);
return true;
}
if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx)) {
*vp = IdToValue(*idp);
return true;
}
if (js_ValueToStringId(cx, idval, idp)) {
vp->setString(JSID_TO_STRING(*idp));
return true;
}
return false;
}
#endif
template<XDRMode mode>
bool
js::XDRAtom(XDRState<mode> *xdr, JSAtom **atomp)