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:
parent
d8b1569efd
commit
8de63f495f
|
@ -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).
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue