Bug fix: don't allow enumeration of the length property in Array.

Properly handle assignments to the Array.length property: if set to a value smaller than the previous length value, destroy all objects found at indexes greater than length.



git-svn-id: http://yate.null.ro/svn/yate/trunk@5584 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
oana 2013-07-16 13:47:17 +00:00
parent d8b1569efd
commit 8de63f495f
2 changed files with 32 additions and 14 deletions

View File

@ -517,7 +517,16 @@ bool JsArray::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* con
{ {
XDebug(DebugAll,"JsArray::runAssign() '%s'='%s' (%s) in '%s' [%p]", XDebug(DebugAll,"JsArray::runAssign() '%s'='%s' (%s) in '%s' [%p]",
oper.name().c_str(),oper.c_str(),oper.typeOf(),toString().c_str(),this); oper.name().c_str(),oper.c_str(),oper.typeOf(),toString().c_str(),this);
if (!JsObject::runAssign(stack,oper,context)) if (oper.name() == YSTRING("length")) {
int newLen = oper.toInteger(-1);
if (newLen < 0)
return false;
for (int i = newLen; i < length(); i++)
params().clearParam(String(i));
setLength(newLen);
return true;
}
else if (!JsObject::runAssign(stack,oper,context))
return false; return false;
int idx = oper.toString().toInteger(-1) + 1; int idx = oper.toString().toInteger(-1) + 1;
if (idx && idx > m_length) if (idx && idx > m_length)
@ -525,6 +534,18 @@ bool JsArray::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* con
return true; return true;
} }
bool JsArray::runField(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
XDebug(DebugAll,"JsArray::runField() '%s' in '%s' [%p]",
oper.name().c_str(),toString().c_str(),this);
if (oper.name() == YSTRING("length")) {
// Reflects the number of elements in an array.
ExpEvaluator::pushOne(stack,new ExpOperation(length()));
return true;
}
return JsObject::runField(stack,oper,context);
}
bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context) bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context)
{ {
XDebug(DebugAll,"JsArray::runNative() '%s' in '%s' [%p]", XDebug(DebugAll,"JsArray::runNative() '%s' in '%s' [%p]",
@ -538,7 +559,6 @@ bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* con
const_cast<String&>(op->name()) = (unsigned int)m_length++; const_cast<String&>(op->name()) = (unsigned int)m_length++;
params().addParam(op); params().addParam(op);
} }
setLength();
ExpEvaluator::pushOne(stack,new ExpOperation(length())); ExpEvaluator::pushOne(stack,new ExpOperation(length()));
} }
else if (oper.name() == YSTRING("pop")) { else if (oper.name() == YSTRING("pop")) {
@ -563,11 +583,6 @@ bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* con
} }
// clear last // clear last
params().clearParam(last); params().clearParam(last);
setLength();
}
else if (oper.name() == YSTRING("length")) {
// Reflects the number of elements in an array.
ExpEvaluator::pushOne(stack,new ExpOperation(length()));
} }
else if (oper.name() == YSTRING("concat")) { else if (oper.name() == YSTRING("concat")) {
// Returns a new array comprised of this array joined with other array(s) and/or value(s). // Returns a new array comprised of this array joined with other array(s) and/or value(s).

View File

@ -2205,6 +2205,15 @@ public:
*/ */
virtual bool runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context); virtual bool runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context);
/**
* Try to evaluate a single field
* @param stack Evaluation stack in use, field value must be pushed on it
* @param oper Field to evaluate
* @param context Pointer to arbitrary object passed from evaluation methods
* @return True if evaluation succeeded
*/
virtual bool runField(ObjList& stack, const ExpOperation& oper, GenObject* context);
protected: protected:
/** /**
* Clone and rename method * Clone and rename method
@ -2224,18 +2233,12 @@ protected:
*/ */
bool runNative(ObjList& stack, const ExpOperation& oper, GenObject* context); bool runNative(ObjList& stack, const ExpOperation& oper, GenObject* context);
/**
* Synchronize the "length" parameter to the internally stored length
*/
inline void setLength()
{ params().setParam("length",String((int)m_length)); }
/** /**
* Set the internal length and the "length" parameter to a specific value * Set the internal length and the "length" parameter to a specific value
* @param len Length of array to set * @param len Length of array to set
*/ */
inline void setLength(long len) inline void setLength(long len)
{ m_length = len; params().setParam("length",String((int)len)); } { m_length = len; }
private: private:
bool runNativeSlice(ObjList& stack, const ExpOperation& oper, GenObject* context); bool runNativeSlice(ObjList& stack, const ExpOperation& oper, GenObject* context);